{"record":{"id":"3821b36907454b2d","repo":"semaphoreui/semaphore","slug":"base64-decode-w","errorCode":null,"errorMessage":"base64 decode: %w","messagePattern":"base64 decode: %w","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"error","filePath":"util/encryption.go","lineNumber":41,"sourceCode":"\n\tgcm, err := newGCM(encodedKey)\n\tif err != nil {\n\t\treturn \"\", err\n\t}\n\n\tnonce := make([]byte, gcm.NonceSize())\n\tif _, err := io.ReadFull(rand.Reader, nonce); err != nil {\n\t\treturn \"\", err\n\t}\n\n\treturn base64.StdEncoding.EncodeToString(gcm.Seal(nonce, nonce, plaintext, nil)), nil\n}\n\n// DecryptAESGCM decrypts an AES-256-GCM ciphertext.\nfunc DecryptAESGCM(encodedCiphertext, encodedKey string) ([]byte, error) {\n\tciphertext, err := base64.StdEncoding.DecodeString(encodedCiphertext)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"base64 decode: %w\", err)\n\t}\n\n\tif encodedKey == \"\" {\n\t\treturn ciphertext, nil\n\t}\n\n\tgcm, err := newGCM(encodedKey)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tnonceSize := gcm.NonceSize()\n\tif len(ciphertext) < nonceSize {\n\t\treturn nil, errors.New(\"ciphertext too short\")\n\t}\n\n\tnonce, payload := ciphertext[:nonceSize], ciphertext[nonceSize:]\n\treturn gcm.Open(nil, nonce, payload, nil)","sourceCodeStart":23,"sourceCodeEnd":59,"githubUrl":"https://github.com/semaphoreui/semaphore/blob/1774ccb71a0a8b82eb74ea24c23ac9ab713de2fa/util/encryption.go#L23-L59","documentation":"Returned by DecryptAESGCM in util/encryption.go when the input ciphertext string is not valid standard base64. The function expects the AES-256-GCM ciphertext to be base64-encoded (nonce prefixed); failing to decode means the stored value is corrupted, truncated, was written in a different encoding (e.g. base64url without padding), or is plaintext from a legacy scheme. The %w wraps encoding/base64's CorruptInputError with the offending byte offset.","triggerScenarios":"Thrown at util/encryption.go:41 when the library encounters an invalid state.","commonSituations":"See trigger scenarios.","solutions":["Check the wrapped CorruptInputError offset to locate the first invalid character in the stored value","If the value came from a legacy or non-encrypted scheme, route it through the legacy plaintext path (an empty key returns the ciphertext unchanged) or migrate it","Re-encrypt the secret with EncryptAESGCM to restore a well-formed base64 blob","Verify the value was not mangled by storage or copy-paste (whitespace, URL-unsafe characters, missing padding)"],"exampleFix":null,"handlingStrategy":"validation","validationCode":null,"typeGuard":null,"tryCatchPattern":null,"preventionTips":[],"tags":[],"backgroundTag":null,"analyzedSha":"1774ccb71a0a8b82eb74ea24c23ac9ab713de2fa","analyzedAt":"2026-09-07T11:00:33.293Z","contentChangedAt":"2026-09-07T11:00:33.293Z","schemaVersion":2},"datasetVersion":"2026-09-16T09:17:16.951Z"}