{"record":{"id":"ba64712d52d66c99","repo":"getsops/sops","slug":"failed-to-read-s-w","errorCode":null,"errorMessage":"failed to read '%s': %w","messagePattern":"failed to read '(.+?)': %w","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"error","filePath":"age/encrypted_keys.go","lineNumber":124,"sourceCode":"\treturn fileKey, err\n}\n\nfunc unwrapIdentities(location string, reader io.Reader, allowMultipleKeysPerLine bool) (ParsedIdentities, error) {\n\tb := bufio.NewReader(reader)\n\tp, _ := b.Peek(14) // length of \"age-encryption\" and \"-----BEGIN AGE\"\n\tpeeked := string(p)\n\n\tswitch {\n\t// An age encrypted file, plain or armored.\n\tcase peeked == \"age-encryption\" || peeked == \"-----BEGIN AGE\":\n\t\tvar r io.Reader = b\n\t\tif peeked == \"-----BEGIN AGE\" {\n\t\t\tr = armor.NewReader(r)\n\t\t}\n\t\tconst privateKeySizeLimit = 1 << 24 // 16 MiB\n\t\tcontents, err := io.ReadAll(io.LimitReader(r, privateKeySizeLimit))\n\t\tif err != nil {\n\t\t\treturn nil, fmt.Errorf(\"failed to read '%s': %w\", location, err)\n\t\t}\n\t\tif len(contents) == privateKeySizeLimit {\n\t\t\treturn nil, fmt.Errorf(\"failed to read '%s': file too long\", location)\n\t\t}\n\t\t// We use Base32 encoding instead of Base64 encoding, since our GPG agent package percent-encodes\n\t\t// the cache ID. Base64 has two characters ('+' and '/') that would end up as a longer sequence,\n\t\t// whence using Base64 encoding can suddenly blow up the cache key to more than GPG's maximum of\n\t\t// 50 characters.\n\t\t// By using 25 bytes, that translate to 25 / 5 * 8 = 40 letters/digits, we have a cache key of\n\t\t// length 47, whose percent-encoding always has 47 characters.\n\t\tcontentsHash := sha256.Sum256(contents)\n\t\tcacheKey := fmt.Sprintf(\"SopsAge%s\", base32.StdEncoding.EncodeToString(contentsHash[:25]))\n\t\tIncorrectPassphrase := func() {\n\t\t\tconn, err := gpgagent.NewConn()\n\t\t\tif err != nil {\n\t\t\t\treturn\n\t\t\t}\n\t\t\tdefer func(conn *gpgagent.Conn) {","sourceCodeStart":106,"sourceCodeEnd":142,"githubUrl":"https://github.com/getsops/sops/blob/13442bb98183887d7a9ac09ec8ab0564673a59d8/age/encrypted_keys.go#L106-L142","documentation":"unwrapIdentities reads an age identity file (decrypting it if needed) with io.ReadAll bounded to 16 MiB. Any read error before that limit is wrapped as \"failed to read '%s': %w\", naming the file location. It indicates the underlying reader failed while consuming the key file, not a key-matching problem.","triggerScenarios":"Loading identities via loadIdentities when io.ReadAll fails on the identity file's reader — permission errors, missing file opened lazily, network filesystem dropout, or a failing custom io.Reader.","commonSituations":"Wrong path or unreadable permissions on the file referenced by SOPS_AGE_KEY_FILE; SSH agent or key provider streams that error mid-read; NFS/network mounts dropping connection during read.","solutions":["Check the file path exists and is readable by the current user (permissions/ownership).","Retry if the failure came from a transient network filesystem error.","Inspect the wrapped cause (%w) to identify the underlying I/O failure and fix that source."],"exampleFix":"// before\n$ ls -l /run/secrets/age-key  # root-only readable\n// after\n$ chmod 600 /run/secrets/age-key && chown $USER /run/secrets/age-key","handlingStrategy":"validation","validationCode":"info, err := os.Stat(location)\nif err != nil {\n    return fmt.Errorf(\"identity file %s not accessible: %w\", location, err)\n}\nif !info.Mode().IsRegular() || info.Size() > 1<<24 {\n    return fmt.Errorf(\"identity file %s is not a regular file or too large\", location)\n}","typeGuard":null,"tryCatchPattern":"keys, err := loadIdentities(loc)\nif err != nil && strings.Contains(err.Error(), \"failed to read\") {\n    // check permissions/mount and retry once\n}","preventionTips":["Check file permissions with os.Stat before loading identities","Avoid reading identities from flaky network mounts; copy locally first","Inspect the wrapped error cause before retrying"],"tags":["age","io","file-read","identity","permissions"],"backgroundTag":"file-read-failed","analyzedSha":"13442bb98183887d7a9ac09ec8ab0564673a59d8","analyzedAt":"2026-09-01T03:53:00.447Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}