{"record":{"id":"2bf8ea6143f22c68","repo":"nodejs/node","slug":"failed-to-read-dictionary-s-s-n","errorCode":null,"errorMessage":"failed to read dictionary [%s]: %s\\n","messagePattern":"failed to read dictionary \\[(.+?)\\]: (.+?)\\\\n","errorType":"console","errorClass":null,"httpStatus":null,"severity":"error","filePath":"deps/brotli/c/tools/brotli.c","lineNumber":925,"sourceCode":"\n  if (file_size_64 > kMaxDictionarySize) {\n    fprintf(stderr, \"dictionary [%s] is larger than maximum allowed: %d\\n\",\n            PrintablePath(context->dictionary_path), kMaxDictionarySize);\n    fclose(f);\n    return BROTLI_FALSE;\n  }\n  context->dictionary_size = (size_t)file_size_64;\n\n  buffer = (uint8_t*)malloc(context->dictionary_size);\n  if (!buffer) {\n    fprintf(stderr, \"could not read dictionary: out of memory\\n\");\n    fclose(f);\n    return BROTLI_FALSE;\n  }\n  bytes_read = fread(buffer, sizeof(uint8_t), context->dictionary_size, f);\n  if (bytes_read != context->dictionary_size) {\n    free(buffer);\n    fprintf(stderr, \"failed to read dictionary [%s]: %s\\n\",\n            PrintablePath(context->dictionary_path), strerror(errno));\n    fclose(f);\n    return BROTLI_FALSE;\n  }\n  fclose(f);\n  context->dictionary = buffer;\n  if (command == COMMAND_COMPRESS) {\n    context->prepared_dictionary = BrotliEncoderPrepareDictionary(\n        BROTLI_SHARED_DICTIONARY_RAW, context->dictionary_size,\n        context->dictionary, BROTLI_MAX_QUALITY, NULL, NULL, NULL);\n    if (context->prepared_dictionary == NULL) {\n      fprintf(stderr, \"failed to prepare dictionary [%s]\\n\",\n              PrintablePath(context->dictionary_path));\n      return BROTLI_FALSE;\n    }\n  }\n  return BROTLI_TRUE;\n}","sourceCodeStart":907,"sourceCodeEnd":943,"githubUrl":"https://github.com/nodejs/node/blob/1b2de5e052fc0fb95fd7fb6846dcec4ade598e9e/deps/brotli/c/tools/brotli.c#L907-L943","documentation":"`fread` on the dictionary file returned fewer bytes than expected (`bytes_read != context->dictionary_size`). The file was opened and sized successfully, but the actual read was short. The buffer is freed and the dictionary path + errno are reported.","triggerScenarios":"An I/O error occurred during the read (disk fault, NFS timeout); the file was truncated between `FileSize` and `fread` (race with another process writing/shrinking it); a read interruption on a network-mounted filesystem.","commonSituations":"Dictionary file being concurrently modified; storage media degradation; NFS mount with intermittent connectivity; file on a FUSE filesystem that returns short reads.","solutions":["Re-read the dictionary file from stable storage.","Ensure no other process is modifying the dictionary file during compression.","Copy the dictionary to a local filesystem (e.g. /tmp) to avoid network I/O issues.","Verify file integrity with `sha256sum` before and after."],"exampleFix":null,"handlingStrategy":"retry","validationCode":"#include <sys/stat.h>\n#include <stdbool.h>\n\nbool dictionary_stable(const char *path, time_t *prev_mtime) {\n    struct stat st;\n    if (stat(path, &st) != 0) return false;\n    if (*prev_mtime != 0 && st.st_mtime != *prev_mtime) return false;\n    *prev_mtime = st.st_mtime;\n    return true;\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Copy the dictionary to a local, read-only location before use.","Ensure no other process writes to the dictionary file during compression.","Verify file integrity with a checksum before and after each run."],"tags":["io","dictionary","read-error","brotli"],"backgroundTag":null,"analyzedSha":"1b2de5e052fc0fb95fd7fb6846dcec4ade598e9e","analyzedAt":"2026-08-13T00:53:24.642Z","schemaVersion":2},"datasetVersion":"2026-08-13T04:17:16.726Z"}