{"record":{"id":"98c66518c0f2bc83","repo":"apache/druid","slug":"exception-during-serialization-of-lookups-using-fi","errorCode":null,"errorMessage":"Exception during serialization of lookups using file [%s]","messagePattern":"Exception during serialization of lookups using file \\[(.+?)\\]","errorType":"exception","errorClass":"IllegalStateException","httpStatus":null,"severity":"error","filePath":"processing/src/main/java/org/apache/druid/query/lookup/LookupSnapshotTaker.java","lineNumber":94,"sourceCode":"      throw new ISE(e, \"Exception during reading lookups from [%s]\", persistFile.getAbsolutePath());\n    }\n  }\n\n  public synchronized void takeSnapshot(String tier, List<LookupBean> lookups)\n  {\n    final File persistFile = getPersistFile(tier);\n\n    try {\n      FileUtils.writeAtomically(\n          persistFile,\n          out -> {\n            objectMapper.writeValue(out, lookups);\n            return null;\n          }\n      );\n    }\n    catch (IOException e) {\n      throw new ISE(e, \"Exception during serialization of lookups using file [%s]\", persistFile.getAbsolutePath());\n    }\n  }\n\n  @VisibleForTesting\n  File getPersistFile(final String tier)\n  {\n    return new File(persistDirectory, StringUtils.format(\"%s.%s\", tier, PERSIST_FILE_SUFFIX));\n  }\n}\n","sourceCodeStart":76,"sourceCodeEnd":104,"githubUrl":"https://github.com/apache/druid/blob/9b90983fd291f26935af934383ce360473179e4d/processing/src/main/java/org/apache/druid/query/lookup/LookupSnapshotTaker.java#L76-L104","documentation":"LookupSnapshotTaker.takeSnapshot serializes the current lookup list to the tier snapshot file via ObjectMapper.writeValue inside a retry/IO action. An IOException during that write (disk full, permissions, I/O failure) is wrapped in this ISE naming the target file.","triggerScenarios":"Calling takeSnapshot when writing the JSON snapshot to getPersistFile(tier) fails with IOException — read-only filesystem, disk full, missing parent directory, or an error from the underlying output stream.","commonSituations":"Lookup snapshots cannot be persisted on nodes with a full or read-only disk, after directory removal, or when the Druid process lacks write permission to the lookup persistence path.","solutions":["Check disk space and free space on the partition holding the snapshot directory","Fix write permissions on the persistence directory for the Druid process user","Ensure the parent directory exists (create it) and check filesystem mount status (read-only mounts)"],"exampleFix":"// before\n// snapshot write fails on read-only mount\n// after\nmount -o remount,rw /path/to/persistence && chmod u+w /path/to/persistence","handlingStrategy":"try-catch","validationCode":"File dir = persistFile.getParentFile();\nif (dir == null || !dir.isDirectory() || !dir.canWrite()) {\n  throw new IllegalStateException(\"Lookup snapshot directory not writable: \" + dir);\n}\nif (dir.getUsableSpace() < MIN_FREE_BYTES) {\n  throw new IllegalStateException(\"Low disk space for lookup snapshot\");\n}","typeGuard":null,"tryCatchPattern":"try {\n  snapshotTaker.takeSnapshot(tier, lookups);\n} catch (ISE e) {\n  if (e.getMessage().startsWith(\"Exception during serialization\")) {\n    logger.error(e.getCause(), \"Failed to persist lookup snapshot; lookups remain in memory\");\n  } else throw e;\n}","preventionTips":["Alert on low disk space for the lookup persistence path","Ensure the Druid process has write permission on the snapshot directory","Verify the mount is not read-only before nodes join the cluster"],"tags":["io","lookup","snapshot","json-serialization","file-write"],"backgroundTag":"file-write-failed","analyzedSha":"9b90983fd291f26935af934383ce360473179e4d","analyzedAt":"2026-09-07T13:32:30.957Z","contentChangedAt":"2026-09-07T13:32:30.957Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}