stanfordnlp/CoreNLP · critical · RuntimeException
Could not open temporary feature index file for reading.
Error message
Could not open temporary feature index file for reading.
What it means
On subsequent training iterations with flags.saveFeatureIndexToDisk, CRFClassifier reloads the feature index written earlier from the temp file via IOUtils.readObjectFromFile. If reading or deserializing fails (file deleted, truncated, or class mismatch), the Exception is wrapped in this RuntimeException since the iteration cannot continue without the index.
Solutions
- Point java.io.tmpdir to a stable private directory (-Djava.io.tmpdir=/your/dir) that auto-cleaners don't touch.
- Disable saveFeatureIndexToDisk to keep the index in memory and restart training.
- Fix the root cause shown in the wrapped exception (permissions, corrupt file, serialization classpath).
Example fix
// before java -Djava.io.tmpdir=/tmp -cp ... edu.stanford.nlp.ie.crf.CRFClassifier ... // after (on a machine where /tmp is auto-cleaned) java -Djava.io.tmpdir=/data/crf-tmp -cp ... edu.stanford.nlp.ie.crf.CRFClassifier ...
Defensive patterns
Strategy: try-catch
Validate before calling
File tmpDir = new File(System.getProperty("java.io.tmpdir"));
if (!tmpDir.canRead()) {
throw new IllegalStateException("tmpdir unreadable; temp feature index files may disappear between iterations");
} Try / catch
try {
classifier.train(files);
} catch (RuntimeException e) {
if (String.valueOf(e.getMessage()).contains("temporary feature index file for reading")) {
// temp file vanished or is corrupt: restart with in-memory index
props.remove("saveFeatureIndexToDisk");
} else throw e;
} Prevention
- Use a private, stable tmpdir (-Djava.io.tmpdir) that auto-cleaners don't touch.
- Avoid sharing tmpdir between concurrent training jobs (colliding featIndexN.tmp names).
- Prefer the in-memory index unless memory constraints force disk usage.
When it happens
Trigger: flags.saveFeatureIndexToDisk=true and the featIndexN.tmp file is missing, unreadable, or corrupt when the next training iteration starts — e.g. a tmp cleaner wiped it, a concurrent job overwrote it, or the earlier write silently failed.
Common situations: Long training on shared machines where /tmp is periodically cleaned; multi-node jobs without shared storage; disk pressure truncating the file; deserialization classpath mismatches.
Understand the failure class
Background: "failed to read file", EACCES, ENOENT and "could not read <path>" errors: when a program can't read a file from disk — this error's family across 49 libraries.
Related errors
- Could not open temporary feature index file for writing.
- Serializing classifier to
- Failed to load segmenter
- Could not create directory <tgtDir.getAbsolutePath()>, as a…
- Could not create directory <tgtDir.getAbsolutePath()>
AI-assisted analysis of stanfordnlp/CoreNLP@1b7edd19c4 (2026-09-10).
Data as JSON: /api/errors/00e680bd5e82e613.
Report an issue: GitHub.
Appendix: source
Thrown at src/edu/stanford/nlp/ie/crf/CRFClassifier.java:1703
if (oneDimWeights != null) {
this.weights = to2D(oneDimWeights, labelIndices, map);
}
// if (flags.useFloat) {
// oneDimWeights = trainWeightsUsingFloatCRF(data, labels, evaluators, i, featureVals);
// } else if (flags.numLopExpert > 1) {
// oneDimWeights = trainWeightsUsingLopCRF(data, labels, evaluators, i, featureVals);
// } else {
// oneDimWeights = trainWeightsUsingDoubleCRF(data, labels, evaluators, i, featureVals);
// }
// save feature index to disk and read in later
if (flags.saveFeatureIndexToDisk) {
try {
log.info("Reading temporary feature index file.");
featureIndex = IOUtils.readObjectFromFile(featIndexFile);
} catch (Exception e) {
throw new RuntimeException("Could not open temporary feature index file for reading.");
}
}
if (i != flags.numTimesPruneFeatures) {
dropFeaturesBelowThreshold(flags.featureDiffThresh);
log.info("Removing features with weight below " + flags.featureDiffThresh + " and retraining...");
}
}
}
public static float[][] to2D(double[] weights, List<Index<CRFLabel>> labelIndices, int[] map) {
float[][] newWeights = new float[map.length][];
int index = 0;
for (int i = 0; i < map.length; i++) {
newWeights[i] = new float[labelIndices.get(map[i]).size()];
final int arrLength = labelIndices.get(map[i]).size();
for (int j = 0; j < arrLength; j++) {
newWeights[i][j] = (float) weights[index++];View on GitHub (pinned to 1b7edd19c4)