questdb/questdb · error · ServerConfigurationException

Async munmap is not supported on Windows

Error message

Async munmap is not supported on Windows

What it means

The config flag cairo.file.async.munmap.enabled (PropertyKey.CAIRO_FILE_ASYNC_MUNMAP_ENABLED, default false) enables Windows-specific asynchronous unmapping via the file opener's freed-memory mechanism, which relies on POSIX APIs absent on Windows. PropServerConfiguration hard-rejects the combination when Os.isWindows() is true so the server fails fast instead of crashing later in native code.

Source

Thrown at core/src/main/java/io/questdb/PropServerConfiguration.java:1817

            this.maxSqlRecompileAttempts = getInt(properties, env, PropertyKey.CAIRO_SQL_MAX_RECOMPILE_ATTEMPTS, 10);

            String value = getString(properties, env, PropertyKey.CAIRO_WRITER_FO_OPTS, "o_none");
            int lopts = CairoConfiguration.O_NONE;
            String[] opts = value.split("\\|");
            for (String opt : opts) {
                int index = WRITE_FO_OPTS.keyIndex(opt.trim());
                if (index < 0) {
                    lopts |= WRITE_FO_OPTS.valueAt(index);
                }
            }
            this.writerFileOpenOpts = lopts;

            this.writerMixedIOEnabled = getBoolean(properties, env, PropertyKey.DEBUG_CAIRO_ALLOW_MIXED_IO, ff.allowMixedIO(this.dbRoot));
            this.fileDescriptorCacheEnabled = getBoolean(properties, env, PropertyKey.CAIRO_FILE_DESCRIPTOR_CACHE_ENABLED, true);
            this.asyncMunmapEnabled = getBoolean(properties, env, PropertyKey.CAIRO_FILE_ASYNC_MUNMAP_ENABLED, false);
            if (asyncMunmapEnabled && Os.isWindows()) {
                throw new ServerConfigurationException("Async munmap is not supported on Windows");
            }
            this.rmdirMaxDepth = getInt(properties, env, PropertyKey.CAIRO_RMDIR_MAX_DEPTH, 5);

            this.inputFormatConfiguration = new InputFormatConfiguration(
                    DateFormatFactory.INSTANCE,
                    DateLocaleFactory.INSTANCE,
                    this.locale
            );

            try (JsonLexer lexer = new JsonLexer(1024, 1024)) {
                inputFormatConfiguration.parseConfiguration(PropServerConfiguration.class, lexer, confRoot, sqlCopyFormatsFile);
            }

            String cairoSQLCopyIdSupplier = getString(properties, env, PropertyKey.CAIRO_SQL_COPY_ID_SUPPLIER, "random");
            this.cairoSQLCopyIdSupplier = Chars.equalsLowerCaseAscii(cairoSQLCopyIdSupplier, "sequential") ? 1 : 0;

            this.cairoSqlCopyMaxIndexChunkSize = getLongSize(properties, env, PropertyKey.CAIRO_SQL_COPY_MAX_INDEX_CHUNK_SIZE, 100 * Numbers.SIZE_1MB);
            this.cairoSqlCopyMaxIndexChunkSize -= (cairoSqlCopyMaxIndexChunkSize % CsvFileIndexer.INDEX_ENTRY_SIZE);

View on GitHub (pinned to 6610ab113b)

Solutions

  1. Set cairo.file.async.munmap.enabled=false (or remove the line) on Windows hosts
  2. Keep OS-specific overrides in separate conf files or env layers so the flag is only enabled for Linux deployments
  3. If you manage config via env vars, unset QDB_CAIRO_FILE_ASYNC_MUNMAP_ENABLED in Windows deployment manifests

Example fix

# before (on Windows)
cairo.file.async.munmap.enabled=true

# after
cairo.file.async.munmap.enabled=false
Defensive patterns

Strategy: validation

Validate before calling

boolean asyncMunmap = Boolean.parseBoolean(firstNonBlank(props.get("cairo.file.async.munmap.enabled"), env.get("QDB_CAIRO_FILE_ASYNC_MUNMAP_ENABLED"), "false"));
if (asyncMunmap && System.getProperty("os.name", "").toLowerCase().contains("win")) {
    throw new IllegalStateException("cairo.file.async.munmap.enabled=true is Linux-only");
}

Try / catch

catch (ServerConfigurationException e) { if (e.getMessage().contains("Async munmap")) log.fatal("unset cairo.file.async.munmap.enabled on Windows deployments"); exit(1); }

Prevention

When it happens

Trigger: Enabling 'cairo.file.async.munmap.enabled=true' (or QDB_CAIRO_FILE_ASYNC_MUNMAP_ENABLED=true) on any Windows host while PropServerConfiguration loads, which happens for ServerMain and for embedded CairoEngine builds that read the same conf root.

Common situations: A server.conf copied from a Linux production box to a Windows developer machine or Windows container; CI running Windows jobs against a shared config; enabling the flag globally in a base image that is deployed to mixed-OS fleets.

Related errors


AI-assisted analysis of questdb/questdb@6610ab113b (2026-08-14). Data as JSON: /api/errors/7732c16f8a91e6b5. Report an issue: GitHub.