{"record":{"id":"f1e214fda8e874de","repo":"AlistGo/alist","slug":"oidc-malformed-jwt-payload-v","errorCode":null,"errorMessage":"oidc: malformed jwt payload: %v","messagePattern":"oidc: malformed jwt payload: (.+?)","errorType":"http","errorClass":null,"httpStatus":400,"severity":"error","filePath":"server/handles/ssologin.go","lineNumber":182,"sourceCode":"\t\t\tuser.Username = user.Username + \"_\" + userID\n\t\t\tif err = db.CreateUser(user); err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t} else {\n\t\t\treturn nil, err\n\t\t}\n\t}\n\treturn user, nil\n}\n\nfunc parseJWT(p string) ([]byte, error) {\n\tparts := strings.Split(p, \".\")\n\tif len(parts) < 2 {\n\t\treturn nil, fmt.Errorf(\"oidc: malformed jwt, expected 3 parts got %d\", len(parts))\n\t}\n\tpayload, err := base64.RawURLEncoding.DecodeString(parts[1])\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"oidc: malformed jwt payload: %v\", err)\n\t}\n\treturn payload, nil\n}\n\nfunc OIDCLoginCallback(c *gin.Context) {\n\tuseCompatibility := setting.GetBool(conf.SSOCompatibilityMode)\n\tmethod := c.Query(\"method\")\n\tif useCompatibility {\n\t\tmethod = path.Base(c.Request.URL.Path)\n\t}\n\tclientId := setting.GetStr(conf.SSOClientId)\n\tendpoint := setting.GetStr(conf.SSOEndpointName)\n\tprovider, err := oidc.NewProvider(c, endpoint)\n\tif err != nil {\n\t\tcommon.ErrorResp(c, err, 400)\n\t\treturn\n\t}\n\toauth2Config, err := GetOIDCClient(c, useCompatibility, \"\", method)","sourceCodeStart":164,"sourceCodeEnd":200,"githubUrl":"https://github.com/AlistGo/alist/blob/843d9dc8149126976b2625911e45a4d3ffd6f2f5/server/handles/ssologin.go#L164-L200","documentation":"Returned by parseJWT (server/handles/ssologin.go:182) when the second dot-separated segment of the id_token cannot be decoded with base64.RawURLEncoding. The payload segment must be unpadded URL-safe base64; standard base64 with '+' or '/' characters, padded '==' output, or any corruption (truncation, character substitution) fails here.","triggerScenarios":"A JWT whose payload was re-encoded by an intermediary (proxy, logging framework) that escaped or padded it; a token pasted or truncated mid-segment; providers emitting padded base64 in the payload.","commonSituations":"Tokens passed through systems that URL-decode and re-encode them; copy-paste of tokens losing characters; custom JWT minting that uses StdEncoding instead of RawURLEncoding.","solutions":["Confirm the token reaches the server byte-identical (log lengths at both ends)","Re-encode the payload with base64.RawURLEncoding if you mint tokens yourself","If the provider emits padded tokens, fetch a fresh token — do not hand-edit segments"],"exampleFix":"// before (minting)\nseg := base64.StdEncoding.EncodeToString(payload) // may contain + / =\n// after\nseg := base64.RawURLEncoding.EncodeToString(payload)","handlingStrategy":"validation","validationCode":"func validRawURLBase64(seg string) bool {\n  _, err := base64.RawURLEncoding.DecodeString(seg)\n  return err == nil\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Never re-encode token segments in transit","Mint JWTs with RawURLEncoding (no padding)","Compare token bytes at producer and consumer to catch corruption"],"tags":["oidc","sso","jwt","base64"],"backgroundTag":null,"analyzedSha":"843d9dc8149126976b2625911e45a4d3ffd6f2f5","analyzedAt":"2026-08-15T12:14:11.722Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}