{"record":{"id":"b8cb98dff67cf195","repo":"getsops/sops","slug":"failed-to-copy-age-decrypted-data-into-bytes-buffe","errorCode":null,"errorMessage":"failed to copy age decrypted data into bytes.Buffer: %w","messagePattern":"failed to copy age decrypted data into bytes\\.Buffer: %w","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"error","filePath":"age/keysource.go","lineNumber":267,"sourceCode":"\t\tif len(ids) == 0 {\n\t\t\tlog.Info(\"Decryption failed\")\n\t\t\treturn nil, formatError(\"failed to load age identities\", nil, errs, unusedLocations)\n\t\t}\n\t\tids.ApplyToMasterKey(key)\n\t}\n\n\tsrc := bytes.NewReader([]byte(key.EncryptedKey))\n\tar := armor.NewReader(src)\n\tr, err := age.Decrypt(ar, key.parsedIdentities...)\n\tif err != nil {\n\t\tlog.Info(\"Decryption failed\")\n\t\treturn nil, formatError(\"failed to create reader for decrypting sops data key with age\", err, errs, unusedLocations)\n\t}\n\n\tvar b bytes.Buffer\n\tif _, err := io.Copy(&b, r); err != nil {\n\t\tlog.Info(\"Decryption failed\")\n\t\treturn nil, fmt.Errorf(\"failed to copy age decrypted data into bytes.Buffer: %w\", err)\n\t}\n\n\tlog.Info(\"Decryption succeeded\")\n\treturn b.Bytes(), nil\n}\n\n// NeedsRotation returns whether the data key needs to be rotated or not.\nfunc (key *MasterKey) NeedsRotation() bool {\n\treturn false\n}\n\n// ToString converts the key to a string representation.\nfunc (key *MasterKey) ToString() string {\n\treturn key.Recipient\n}\n\n// ToMap converts the MasterKey to a map for serialization purposes.\nfunc (key *MasterKey) ToMap() map[string]interface{} {","sourceCodeStart":249,"sourceCodeEnd":285,"githubUrl":"https://github.com/getsops/sops/blob/13442bb98183887d7a9ac09ec8ab0564673a59d8/age/keysource.go#L249-L285","documentation":"sops failed to read the plaintext output produced by the age decryption stream into memory. After a successful age.Decrypt call, the resulting reader r is copied into a bytes.Buffer; an error here means the underlying reader (e.g. the armored/file stream wrapping the data key) returned an I/O error mid-read, so decryption is aborted. This indicates the decrypted stream was corrupt, truncated, or unreadable, not that key decryption itself failed.","triggerScenarios":"MasterKey.Decrypt (age/keysource.go) calls io.Copy into a bytes.Buffer and the underlying reader returns an error before EOF: corrupted or truncated sops file, an age plugin binary that exits early, or a reader that errors after partial output.","commonSituations":"Sops-encrypted files damaged by partial writes or bad git merges; age plugin binaries (age-plugin-yubikey etc.) crashing or emitting garbage; piping truncated input into sops decrypt; filesystem/permission problems surfacing as read errors mid-stream.","solutions":["Verify the encrypted file is complete and unmodified (git checkout the original file, re-download, or re-encrypt from source).","Re-run sops with SOPS_AGE_DEBUG or general logging to see which key/reader errored.","If using an age plugin recipient, confirm the plugin binary is installed, executable, and works with a direct age round-trip.","Check disk space and file permissions on the input file; retry the decrypt.","Regenerate the data key by re-encrypting the file with a known-good age identity."],"exampleFix":"// before: decrypting a truncated file pulled from a partial sync\nsops -d secrets.enc.yaml\n// failed to copy age decrypted data into bytes.Buffer: unexpected EOF\n\n// after: restore the complete file, then decrypt\ngit checkout -- secrets.enc.yaml\nsops -d secrets.enc.yaml","handlingStrategy":"try-catch","validationCode":"// Go caller\nif info, err := os.Stat(encFile); err != nil || info.Size() == 0 {\n    return fmt.Errorf(\"encrypted file missing or empty: %s\", encFile)\n}\n// verify round-trip once at deploy time:\n// sops -d encFile > /dev/null && echo ok","typeGuard":null,"tryCatchPattern":"plaintext, err := key.Decrypt()\nif err != nil {\n    var agg *sopskey.ErrDecrypt  // or use errors.Is/As on the wrapped cause\n    if errors.As(err, &agg) {\n        log.Printf(\"age decrypt failed (corrupt/truncated stream?): %v\", err)\n        return fmt.Errorf(\"re-encrypt from source or restore file: %w\", err)\n    }\n    return err\n}","preventionTips":["Keep encrypted files in version control so truncated/corrupted copies can be restored.","Test age plugin round-trips (age encrypt/decrypt) on every machine where sops runs.","Run sops decrypt as a CI smoke test to catch corrupt files early.","Monitor disk space; partial writes are a common cause of truncated streams.","Pin sops and age plugin versions across environments."],"tags":["age","decryption","io"],"backgroundTag":"age-decrypt-stream-failed","analyzedSha":"13442bb98183887d7a9ac09ec8ab0564673a59d8","analyzedAt":"2026-09-01T03:53:00.447Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}