---
title: "Google Workspace SMTP Relay 550 5.7.1 Invalid Credentials on a Dual-Stack Server"
canonical: "https://techwiki.co.uk/linux/google-smtp-relay-550-invalid-credentials-ipv6"
author: "Adam Birds"
article_type: "documentation"
published: "2026-10-31T15:36:33.057Z"
updated: "2026-10-31T15:36:33.059Z"
categories: ["Linux"]
tags: ["google-workspace","ipv6","php-fpm","smtp"]
---**Mail sent through `smtp-relay.gmail.com` is rejected at `MAIL FROM` even though the server's IPv4 address is allowlisted in the Google Workspace SMTP relay settings.**

```text
550-5.7.1 Invalid credentials for relay [<server-ipv6>]. The IP
550-5.7.1 address you've registered in your Workspace SMTP Relay service
550-5.7.1 doesn't match the domain of the account this email is being sent
550 5.7.1 from.
```

The address in square brackets is the giveaway: it is the server's IPv6 address, not the IPv4 address that was allowlisted.

## Cause

`smtp-relay.gmail.com` has both A and AAAA records. On a dual-stack server the default address selection prefers IPv6, so the connection arrives from an address the relay does not recognise. The relay accepts the TCP connection, `EHLO` and `STARTTLS`, then refuses the message at `MAIL FROM`, which makes it look like a credentials or domain problem.

## Fix

These steps make the server prefer IPv4 for outbound connections. Inbound traffic is unaffected, and IPv6 stays enabled.

### Confirm which address is rejected

Test each address family without sending a message. The script stops after `RCPT TO`. Save it as `relay-test.py`, replacing the placeholders:

```python
import smtplib, socket

for family, name in ((socket.AF_INET, 'ipv4'), (socket.AF_INET6, 'ipv6')):
    try:
        addr = socket.getaddrinfo('smtp-relay.gmail.com', 587, family)[0][4][0]
        s = smtplib.SMTP(timeout=15)
        s._host = 'smtp-relay.gmail.com'
        s.connect(addr, 587)
        s.ehlo('<your-domain>')
        s.starttls()
        s.ehlo('<your-domain>')
        print(name, 'MAIL', s.mail('no-reply@<your-domain>'))
        print(name, 'RCPT', s.rcpt('postmaster@<your-domain>'))
        s.rset()
        s.quit()
    except Exception as e:
        print(name, 'FAIL', repr(e))
```

Then run it on the server:

```bash
python3 relay-test.py
```

If IPv4 returns `250` and IPv6 returns `550 5.7.1`, this article applies.

### Prefer IPv4

Uncomment the existing precedence line in `/etc/gai.conf`, or add it if it is missing:

```bash
sudo sed -i 's|^#precedence ::ffff:0:0/96  100|precedence ::ffff:0:0/96  100|' /etc/gai.conf
grep '^precedence' /etc/gai.conf
```

### Restart PHP-FPM

Running PHP-FPM workers can keep using IPv6 after this change, so restart the service. Adjust the version to match the server:

```bash
sudo systemctl restart php8.5-fpm
```

## Verify

Check the connection from inside PHP-FPM, not only from the command line. Command-line PHP picks up the change immediately, so it can pass while the website still fails.

Save this as a temporary script that is not publicly reachable, and run it through the PHP-FPM pool:

```php
<?php
$s = stream_socket_client('tcp://smtp-relay.gmail.com:587', $errno, $error, 10);
echo 'local=', stream_socket_get_name($s, false), ' peer=', stream_socket_get_name($s, true), "\n";
```

The `local=` value should be the server's IPv4 address. Then send a real message from the application and delete the temporary script.

## Notes

- `/etc/gai.conf` sets a preference only. If IPv4 to the relay fails, the connection can still fall back to IPv6 and be rejected again.
- Fully disabling IPv6 is a much larger change. Web servers listening on `[::]`, firewall rules and AAAA records used by a reverse proxy may all depend on it.
- Adding the IPv6 address to the relay allowlist, or using SMTP authentication, should also work, but neither was tested here.
- A PHP-FPM reload was not tested. Only a full restart was confirmed.
- Tested on Ubuntu 26.04 with PHP 8.5, WordPress and WP Mail SMTP.
