apache/cassandra · error · IOException

Failed to save Bloom filter for SSTable:

Error message

Failed to save Bloom filter for SSTable: 

What it means

FilterComponent.save() wraps any IOException encountered while persisting a SSTable's Bloom filter (the FILTER component) and rethrows it with the descriptor's base file name appended, preserving the cause. Cassandra throws this when flushing or streaming fails to write the bloom filter to disk successfully.

Source

Thrown at src/java/org/apache/cassandra/io/sstable/format/FilterComponent.java:86

        {
            throw new IOException("Failed to load Bloom filter for SSTable: " + descriptor.baseFile(), ex);
        }
    }

    public static void save(IFilter filter, Descriptor descriptor, boolean deleteOnFailure) throws IOException
    {
        File filterFile = descriptor.fileFor(Components.FILTER);
        try (FileOutputStreamPlus stream = filterFile.newOutputStream(File.WriteMode.OVERWRITE))
        {
            filter.serialize(stream, descriptor.version.hasOldBfFormat());
            stream.flush();
            stream.sync();
        }
        catch (IOException ex)
        {
            if (deleteOnFailure)
                descriptor.fileFor(Components.FILTER).deleteIfExists();
            throw new IOException("Failed to save Bloom filter for SSTable: " + descriptor.baseFile(), ex);
        }
    }

    /**
     * Optionally loads a Bloom filter.
     * If the filter is not needed (FP chance is neglectable), it returns {@link FilterFactory#AlwaysPresent}.
     * If the filter is expected to be recreated for various reasons the method returns {@code null}.
     * Otherwise, an attempt to load the filter is made and if it succeeds, the loaded filter is returned.
     * If loading fails, the method returns {@code null}.
     *
     * @return {@link FilterFactory#AlwaysPresent}, loaded filter or {@code null} (which means that the filter should be rebuilt)
     */
    public static IFilter maybeLoadBloomFilter(Descriptor descriptor, Set<Component> components, TableMetadata metadata, ValidationMetadata validationMetadata)
    {
        double currentFPChance = validationMetadata != null ? validationMetadata.bloomFilterFPChance : Double.NaN;
        double desiredFPChance = metadata.params.bloomFilterFpChance;

        IFilter filter = null;

View on GitHub (pinned to 88fd0f6a0e)

Solutions

  1. Check disk space and filesystem health (df -h, dmesg for I/O errors) on the data directory and free space or fix the disk
  2. Retry the flush/compaction after resolving the I/O condition; the failed filter file is deleted automatically when deleteOnFailure is set
  3. Verify permissions on the SSTable directory allow the Cassandra process to create files
  4. If it recurs on specific disks, run nodetool scrub or move the node out of rotation and rebuild it

Example fix

// before: ignoring disk pressure and retrying immediately
try { writeSSTable(); } catch (IOException e) { retry(); }
// after: check disk space and handle IOException specifically
try { writeSSTable(); }
catch (IOException e) {
    if (e.getMessage().startsWith("Failed to save Bloom filter")) {
        ensureDiskSpace(dataDir);
        retryWithBackoff();
    } else throw e;
}
Defensive patterns

Strategy: try-catch

Validate before calling

// before flush/save
if (Files.getUsableSpace(dataDir.toPath()) < requiredBytes) { freeSpace(); }
descriptor.fileFor(Components.FILTER).getParentFile().canWrite();

Try / catch

try { filterComponent.save(descriptor, filter, cleanup); }
catch (IOException e) {
    if (e.getMessage().startsWith("Failed to save Bloom filter")) {
        logger.error("Bloom filter save failed for {}", descriptor.baseFile(), e.getCause());
        checkDiskSpaceAndFilesystem();
    } else throw e;
}

Prevention

When it happens

Trigger: Calling save() during SSTable flush/compaction/streaming when writing Components.FILTER to disk fails: disk full, I/O error, directory removed, or sync() failure. If deleteOnFailure is set, the partial filter file is deleted before rethrowing.

Common situations: Disk-full or disk-failure during flush; snapshot/restore operations with missing data directories; filesystem errors (EIO, ENOSPC) on the data volume; concurrent deletion of the descriptor's directory.

Understand the failure class

Background: "failed to write file", "Could not save figure", "Error saving remote file" — file write failed: causes and fixes across languages and libraries — this error's family across 38 libraries.

Related errors


AI-assisted analysis of apache/cassandra@88fd0f6a0e (2026-09-10). Data as JSON: /api/errors/e20358419aba41ea. Report an issue: GitHub.