{"record":{"id":"0ac4059e980b164b","repo":"OpenNHP/opennhp","slug":"error-reading-file-v-0ac405","errorCode":null,"errorMessage":"error reading file: %v","messagePattern":"error reading file: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"endpoints/server/msghandler.go","lineNumber":761,"sourceCode":"\n\tencoder := json.NewEncoder(file)\n\tencoder.SetIndent(\"\", \"  \")\n\treturn encoder.Encode(drgMsg)\n}\n\n// read data-<doId>.json to DRGMsg Object\nfunc ReadZdtoConfig(doId string) (common.DRGMsg, error) {\n\tetcDir := filepath.Join(ExeDirPath, \"etc\", \"ztdo\")\n\tconfigFilePath := filepath.Join(etcDir, \"data-\"+doId+\".json\")\n\tfile, err := os.Open(configFilePath)\n\tif err != nil {\n\t\treturn common.DRGMsg{}, fmt.Errorf(\"could not open file: %v\", err)\n\t}\n\tdefer file.Close()\n\n\tfileContentByte, err := io.ReadAll(file)\n\tif err != nil {\n\t\treturn common.DRGMsg{}, fmt.Errorf(\"error reading file: %v\", err)\n\t}\n\n\tvar config common.DRGMsg\n\n\terr = json.Unmarshal(fileContentByte, &config)\n\tif err != nil {\n\t\treturn common.DRGMsg{}, fmt.Errorf(\"json parsing error: %s\", err)\n\t}\n\treturn config, nil\n}\n\n// HandleRelayForward processes a decrypted NHP_RLY message from the standard\n// Noise pipeline.  The relay's identity has already been validated by\n// validatePeer as part of the standard decryption flow.\n//\n// The message body is a JSON-encoded RelayForwardMsg containing:\n//   - SourceAddr:  the real client's IP/port\n//   - InnerPacket: base64-encoded inner NHP packet (encrypted by agent)","sourceCodeStart":743,"sourceCodeEnd":779,"githubUrl":"https://github.com/OpenNHP/opennhp/blob/6e04ca5ff03222a699c24205cd4bf8fee9af7ffe/endpoints/server/msghandler.go#L743-L779","documentation":"ReadZdtoConfig opened `etc/ztdo/data-<doId>.json` but io.ReadAll failed while reading its contents. The wrapped OS error (commonly EIO from failing disk or I/O on a network volume) prevents loading the DRGMsg.","triggerScenarios":"HandleDHPDARMessage/HandleDHPDAVMessage or SaveZdtoConfig trigger ReadZdtoConfig on a config file whose read fails — rare, typically hardware/IO errors, detached network storage, or file changed to a special file (device/FIFO).","commonSituations":"etc/ztdo lives on an NFS/EBS volume that dropped; underlying disk errors; someone replaced the JSON file with a named pipe or device node.","solutions":["Check the wrapped OS error (dmesg / storage health) and repair the underlying disk or remount the volume.","Verify data-<doId>.json is a regular file, not a device/FIFO, and replace it if corrupted.","Re-publish the ZTDO via the DRG flow to rewrite the config from source.","If on network storage, ensure the mount is healthy before retrying."],"exampleFix":"// before: no file-type check\nfile, _ := os.Open(configFilePath)\n// after: ensure a regular file before reading\nfi, _ := file.Stat()\nif !fi.Mode().IsRegular() {\n    return common.DRGMsg{}, fmt.Errorf(\"%s is not a regular file\", configFilePath)\n}","handlingStrategy":"fallback","validationCode":"p := filepath.Join(exeDir, \"etc\", \"ztdo\", \"data-\"+doId+\".json\")\nfi, err := os.Stat(p)\nif err == nil && !fi.Mode().IsRegular() {\n    return fmt.Errorf(\"%s is not a regular file\", p)\n}","typeGuard":"func isReadableRegularFile(p string) bool {\n    fi, err := os.Stat(p)\n    return err == nil && fi.Mode().IsRegular()\n}","tryCatchPattern":"msg, err := ReadZdtoConfig(doId)\nif err != nil && strings.Contains(err.Error(), \"error reading file\") {\n    log.Error(\"ztdo IO failure: %v\", err) // fallback to cache/re-publish\n    return loadFromBackupOrRepublish(doId)\n}","preventionTips":["Monitor storage health (SMART, dmesg) on the server volume.","Keep configs on local reliable disk rather than flaky network mounts.","Back up etc/ztdo so damaged configs can be restored."],"tags":["filesystem","io","config"],"backgroundTag":"file-read-failed","analyzedSha":"6e04ca5ff03222a699c24205cd4bf8fee9af7ffe","analyzedAt":"2026-09-07T15:44:59.941Z","contentChangedAt":"2026-09-07T15:44:59.941Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}