{"record":{"id":"da39b2ce9f4904a1","repo":"MHSanaei/3x-ui","slug":"wireguard-presharedkey-w","errorCode":null,"errorMessage":"wireguard preSharedKey: %w","messagePattern":"wireguard preSharedKey: %w","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/xray/api.go","lineNumber":639,"sourceCode":"\t\t\tAuth: auth,\n\t\t}), nil\n\tcase \"wireguard\":\n\t\tpubB64, err := getRequiredUserString(user, \"publicKey\")\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tpubHex, err := wgutil.KeyToHex(pubB64)\n\t\tif err != nil {\n\t\t\treturn nil, fmt.Errorf(\"wireguard publicKey: %w\", err)\n\t\t}\n\n\t\tpskB64, err := getOptionalUserString(user, \"preSharedKey\")\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tpskHex, err := wgutil.KeyToHex(pskB64)\n\t\tif err != nil {\n\t\t\treturn nil, fmt.Errorf(\"wireguard preSharedKey: %w\", err)\n\t\t}\n\n\t\tallowed := collectStringSlice(user[\"allowedIPs\"])\n\t\tif len(allowed) == 0 {\n\t\t\treturn nil, common.NewError(\"wireguard: allowedIPs required\")\n\t\t}\n\n\t\tkeepAlive, err := getOptionalUserString(user, \"keepAlive\")\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\n\t\treturn serial.ToTypedMessage(&wireguard.PeerConfig{\n\t\t\tPublicKey:    pubHex,\n\t\t\tPreSharedKey: pskHex,\n\t\t\tAllowedIps:   allowed,\n\t\t\tKeepAlive:    keepAlive,\n\t\t}), nil","sourceCodeStart":621,"sourceCodeEnd":657,"githubUrl":"https://github.com/MHSanaei/3x-ui/blob/ad32144c42455696ea9f14e12168beac3e25f5d2/internal/xray/api.go#L621-L657","documentation":"Same KeyToHex validation applied to the optional 'preSharedKey'. Because the field is optional, an absent key yields \"\" from getOptionalUserString — so reaching this error means a value WAS provided and it is malformed (bad base64 or not 32 bytes). An empty/absent PSK does not error; only a present-but-invalid one does.","triggerScenarios":"Setting preSharedKey to a hex string, a PSK of the wrong length, or a value with stray characters/whitespace; also pasting the string 'none' or 'false' as a placeholder instead of removing the field.","commonSituations":"Config migrations carrying hex-form PSKs; users entering placeholder text in an optional field; PSK copied with a trailing newline from a file.","solutions":["Either remove the preSharedKey field entirely (optional, valid), or supply a proper 32-byte base64 key generated by 'wg genpsk'.","Same length check as publicKey: 43 unpadded base64 chars; convert hex if that's what you have.","Trim whitespace/newlines when copying PSKs out of files or chat messages."],"exampleFix":"// before\nuser[\"preSharedKey\"] = \"none\"\n\n// after\n// option A: no PSK — omit the key entirely\n// option B: real PSK from `wg genpsk`\nuser[\"preSharedKey\"] = base64FromWgGenpsk","handlingStrategy":"validation","validationCode":"// PSK: either omit or validate like any 32-byte base64 key\nif psk, present := user[\"preSharedKey\"]; present {\n    s, _ := psk.(string)\n    if !isValidWGKeyB64(s) {\n        delete(user, \"preSharedKey\") // optional field: removal is safe\n    }\n}","typeGuard":"null","tryCatchPattern":"if strings.Contains(err.Error(), \"wireguard preSharedKey\") {\n    // remove the field or supply a `wg genpsk` value; no retry\n}","preventionTips":["Generate PSKs exclusively with wg genpsk.","Never put placeholder text ('none','false','-') in optional crypto fields — omit the key instead."],"tags":["wireguard","xray","crypto","validation"],"backgroundTag":null,"analyzedSha":"ad32144c42455696ea9f14e12168beac3e25f5d2","analyzedAt":"2026-08-15T11:13:23.905Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}