One client authenticates with the shared key and another rejects it, and the characters you pasted look the same on both sides. They probably are the same characters; the difference is which decoding rule the file applies to them. A quoted string is taken literally, a token beginning with 0x is read as hexadecimal, and a token beginning with 0s is read as Base64. Only one of those three spellings means what you intended, so the fix is usually a conversion rather than a better password.

The symptom points at encoding, not ciphers

When the two ends hold different bytes, negotiation still succeeds and the proof fails afterwards. The log then reports an integrity or HMAC failure rather than an algorithm mismatch, because a proposal was chosen and the authentication step did not match. That line never mentions the shape of the secret.

The stage is the clue. A failure arriving after a chosen proposal means both sides agreed on everything except key material, whereas "no proposal chosen" belongs to policy or cipher suites. An integrity check that fails while the password looks right is the visible face of an encoding mismatch.

One secret, three ways the file can read it

For the four-byte value key1, hexadecimal and Base64 are two re-encodings of the same bytes, and only the leading characters tell the parser which one it is holding. swanctl credentials follow the same convention, so a value moved between the two interfaces keeps its meaning only when its prefix travels with it.

10.20.0.5 %any : PSK "key1"
10.20.0.5 %any : PSK 0x6b657931
10.20.0.5 %any : PSK 0sa2V5MQ==

Two details in that block cost the most time. Hexadecimal digits accept either case, so 0x6b657931 and 0x6B657931 are the same value, but an odd number of characters is silently misread rather than rejected, which shifts every byte after the cut. Base64 padding belongs to the value, so a string pasted without its trailing = signs decodes into different bytes instead of failing loudly.

A profile that decoded the value once has already converted it, so decoding again produces different bytes and an authentication failure that reads like a wrong password. Quoting is the safe direction for anything ambiguous, because the contents are literal even when they begin with an encoding marker.

Where the Base64 text comes from

Profile exports and vendor portals often hand over the key already encoded, usually in a data field that was never meant to be typed by hand. Either unwrap that value and store the decoded text in quotes, or leave it encoded with the marker in front. Doing half of each is what breaks. Either path works only if the whole value survives the copy.

Both directions are one command each, and they are worth keeping in the ticket as the exact operation that produced the stored value. Run them in this order:

printf '%s' 'a2V5MQ==' | base64 -d
printf '%s' 'key1' | base64

Pasting encoded text as if it were plain is the expensive mistake. The file hashes the characters exactly as written, the derived key comes out roughly a third longer than the one the peer computed, and every attempt fails the same way with no warning, because the parser followed the rule it was given.

Confirm which bytes each peer actually uses

Read the daemon's view of the connection first and the authentication result second, rather than guessing a cause from the error string. Comparing the stored length is a fast sanity check, since encoded text is longer than the bytes it represents. Then confirm which identity row matched, because a correct secret filed under the wrong peer fails identically to a wrong one. Row order decides that: the first match wins, so a broad %any line near the top quietly replaces the specific row you just edited.

Reload instead of restarting once the file is right. ipsec rereadsecrets refreshes the IKE daemon's copy, and a swanctl setup loads credentials through its own command. A restart drops every established association and destroys the comparison you were trying to make.

None of these checks requires exposing the secret. A length, an identity selector and a row position explain most failures of this kind before anyone needs a hex dump.

Change the file without hiding the result

Restrict the file to the daemon's account, and keep live secrets out of tickets, chat and screenshots, because a pasted key is a leak rather than a diagnostic. It also outlives the incident that produced it.

Test from a client whose configuration you control, confirm authentication succeeds, and then confirm the tunnel carries traffic. A reload that fixes the handshake while routing stays broken is a different problem, and it becomes visible as soon as the secret stops moving.

Tënë sô zo