ErrLookup › Background articles › "unsupported platform" / "not supported on this platform" errors: what they mean and how to fix them
"unsupported platform" / "not supported on this platform" errors: what they mean and how to fix them
"Unsupported platform", "not supported on this platform", and similar messages appear when a library checks your operating system or CPU architecture at startup and refuses to run because no qualified binary, native module, or platform implementation exists for it. This article explains where these hard platform gates come from, why they usually fire before any real work happens, and the fixes that work across libraries: run on a supported platform or container, provide explicit configuration that bypasses platform-specific defaults, or fall back to a non-native mode.
Distilled from 111 documented records across 47 repositories.
Background
Errors in this family are deliberate platform gates, not bugs. A library that ships native binaries (pnpm's store resolver, esbuild and the native TypeScript compiler in Deno, Cube Store, cloudflared in 9router, ONNX Runtime in GitNexus) or that depends on OS facilities (systemd in Teleport's updater, Unix signals in Codex's daemon, /proc and sandbox-exec/unshare in sandboxing and metrics code) has a finite list of (OS, architecture) combinations it was built and tested for. When the runtime detects a value outside that list — process.platform in Node, std::env::consts::OS/ARCH in Rust, RUBY_PLATFORM in Ruby, env::consts::OS mapped to a package tag in Zed — it fails immediately, usually before touching the network or any file. The message typically interpolates the offending platform string so you can see exactly what the library saw.
From the caller's side these errors look abrupt because they fire deterministically on the first invocation, often at a stage far removed from what you were trying to do: pnpm panics while resolving the default store directory, Deno bails before downloading the tsc compiler, CocoaPods fails during installer setup because a pod resolved to zero platform/target combinations. A common variant is the fail-closed stub: Rust crates compile a cfg(not(unix)) or catch-all arm whose only job is to return an error (Codex's pid-backend terminate_process, RustFS's Connect registration bootstrap, openhuman's service and process-tree stubs, Deno's node shim). These exist to keep the crate cross-compilable while refusing to weaken guarantees — security models built on O_NOFOLLOW, owner checks, and 0700 directories simply do not translate to non-Unix targets.
The family varies in what "supported" means per library. Some gates are compiled-in and absolute: Gradle's PathTraversalChecker asserts the JVM reports a separator it knows and is effectively unreachable on standard JDKs, and its native plugin families are exactly windows, linux, macos. Others are configuration-shaped rather than platform-shaped: Bundler rejects a lockfile missing your local platform (fixable with bundle lock --add-platform) and validates the symbols you may use in platforms: blocks; mise rejects unknown platform-string qualifiers like distro names. A few are guards against misuse rather than genuine port limits — running ruby's win32/mkexports.rb outside a Windows build, or docker-sync probing the macOS-only fswatch dependency on Linux.
One important pattern across records: sometimes the platform check is avoidable through configuration. pnpm's store-dir panic only happens when the OS-specific default must be computed — an explicit store-dir skips it. GitNexus blocks only local embeddings; HTTP embedding mode or skipping --embeddings works everywhere. Cube can run Cube Store as a separate service or via Docker instead of spawning a local native binary. The gate is on the platform-specific code path, not necessarily on the whole tool.
Common causes
- Unsupported OS or architecture for shipped native binaries. The library maps process.platform / arch (or the Rust/Java equivalents) onto a fixed table of qualified binaries and your combination — FreeBSD, riscv64, 32-bit arm, darwin/x64 for onnxruntime-node — has no entry. Deno's esbuild and native-tsc tables, Cube Store, 9router's cloudflared mapping, ECC's release qualification, and GitButler's installer keys all work this way.
- Non-Unix target hitting a Unix-only fail-closed stub. Rust crates compile cfg(not(unix)) stubs that unconditionally error so the crate stays cross-compilable: Codex's daemon lifecycle and pid backend, RustFS's Connect bootstrap, Deno's node shim. The whole feature (signals, flock, Unix sockets, O_NOFOLLOW) is intentionally Unix-only by design.
- Platform-specific default computed where none exists. pnpm panics on any OS outside linux/macos/windows while resolving the default store-dir; the panic only happens when no explicit store-dir is configured. Similar code computes per-OS paths or manager handles and bails in the catch-all arm (Zed's Copilot binary path, openhuman's service installer).
- Missing or wrong platform in lockfiles and platform declarations. Bundler raises when the running platform is not in Gemfile.lock's PLATFORMS (fix with bundle lock --add-platform) and when an unknown symbol like :mri or :linux is used in platforms: blocks. CocoaPods raises when a pod resolves to zero platform/target combinations because the target's platform or spec support mismatched.
- Missing OS subsystem the feature depends on. Teleport's autoupdate updater returns its not-supported sentinel when systemd is not the init system — common in containers and WSL. Caveman's OS network isolation requires /usr/bin/sandbox-exec (macOS) or /usr/bin/unshare with user namespaces (Linux).
- Wrong platform-string format or segment order. Mise rejects qualifiers outside its closed allowlist (gnu, glibc, musl, msvc, baseline, musl-baseline) and mis-ordered strings like linux-musl-x64 where musl lands in the arch slot. Gradle's native plugin only maps names to the windows/linux/macos families and throws on freebsd, solaris, or typos like macosx.
- Running a build-time or macOS-only tool on the wrong host. Ruby's win32/mkexports.rb raises unless RUBY_PLATFORM matches a Windows toolchain; docker-sync forbids the fswatch dependency off macOS (including via rsync's default watch strategy). These gates fire on direct invocation outside the intended environment.
What usually fixes it
- Run on a supported platform: move the workload to linux/macos/windows on x86_64 or aarch64 — via a Linux container, Docker, WSL, or a standard CI runner — since that is what the library actually qualified and tested.
- Bypass the platform-specific default with explicit configuration: set an explicit store-dir in pnpm, point DENO_TSC_BIN at a self-built tsc, or pre-place the native binary (cloudflared, cubestored) so the platform lookup never runs.
- Fall back to a non-native or in-process mode: skip --embeddings or use HTTP embeddings in GitNexus, use caveman's installNetworkDeny() shim, run Cube Store as a standalone service or official Docker image, or use --no-check in Deno.
- Fix platform metadata rather than the platform: add the missing entry with bundle lock --add-platform and commit it, use only documented platform symbols/family names, and keep os-arch-qualifier ordering in platform strings.
- Gate the feature at compile time or startup: cfg(unix) call sites and CLI subcommands, process.platform feature flags in install/bootstrap scripts, and CI matrices that assert the platform before invoking installers.
- Treat the error as intentional and check errors.Is / the exact message instead of string-matching or trying to bypass it — several of these guards (RustFS, Codex, Teleport) are deliberate fail-closed design decisions, and the sanctioned extension point is upstream (adding a match arm or platform module), not catching the error.
Documented occurrences
- unsupported operating system: {} (pnpm/pnpm)
- Unknown file separator: {File.separatorChar} (gradle/gradle)
- Connect registration bootstrap requires Unix owner and permission guarantees (rustfs/rustfs)
- cave_sandbox_os_network_isolation_unavailable: cave_sandbox_os_network_isolation_unavailable (JuliusBrussee/caveman)
- Your bundle only supports platforms #{@platforms.map(&:to_s)} but your local platform is #{Bundler.local_platform}. Add the current platform to the lockfile with `bundle lock --add-platform #{Bundler.local_platform}` and try again. (ruby/rubygems)
- pid-managed app-server shutdown is unsupported on this platform (openai/codex)
- Fswatch is not expected to run on platforms other then MacOS (EugenMayer/docker-sync)
- Local semantic embeddings are unavailable on macOS Intel (darwin/x64). The bundled ONNX Runtime package (onnxruntime-node) does not ship a darwin/x64 native binding, so the local embedding model cannot load here. ONNX_WEB_BACKEND=wasm does not help: the failure happens while importing the native runtime, before any backend can be selected. Forcing GITNEXUS_EMBEDDING_DEVICE=wasm (or cpu) does not help either, for the same reason. Use one of these instead: - Run analyze without --embeddings (all other indexing still works). - Point GITNEXUS_EMBEDDING_URL (with GITNEXUS_EMBEDDING_MODEL) at an OpenAI-compatible /v1/embeddings endpoint to embed over HTTP. - Run GitNexus on Linux or in Docker, where the native binding ships. - Run GitNexus on Apple Silicon (darwin/arm64), which ships a binding. - Use a future GitNexus build that restores darwin/x64 ONNX support. (abhigyanpatwari/GitNexus)
- unsupported Copilot language server platform: {platform} (zed-industries/zed)
- Unsupported qualifier '{}'. Supported: gnu, glibc, musl, msvc, baseline, musl-baseline (jdx/mise)
- codex app-server daemon lifecycle is only supported on Unix platforms (openai/codex)
- unsupported platform: #{platform} (ruby/ruby)
- Unable to detect libc on not linux os (cube-js/cube)
- not supported on this platform (gravitational/teleport)
- `#{p}` is not a valid platform. The available options are: #{VALID_PLATFORMS.inspect} (ruby/ruby)
- Could not download '#{pod_name}' pod, depended upon by #{requiring_targets.to_sentence}. There is either no platform to build for, or no target to build. (CocoaPods/CocoaPods)
- Could not install '#{pod_name}' pod, depended upon by #{requiring_targets.to_sentence}. There is either no platform to build for, or no target to build. (CocoaPods/CocoaPods)
- Unrecognized platform `#{platform}`. Valid platforms: #{VALID_PLATFORMS.join(', ')} (CocoaPods/CocoaPods)
- Service management is supported on macOS, Linux, and Windows only (tinyhumansai/openhuman)
- Automatic CLI installation is not supported on Windows. To use the But CLI, you have two options: 1. Copy the executable to a directory in your PATH: copy "{}" "%LOCALAPPDATA%\Microsoft\WindowsApps\{}" 2. Add the current location to your PATH environment variable: - Press the Win key and select 'System' - Type 'Environment' into the search box and select 'edit variables for your account' - Under 'User variables', select 'Path' and click 'Edit' - Click 'New' and add: {} After either option, restart your terminal to use the 'but' command. (gitbutlerapp/gitbutler)
…and 91 more across the corpus — use search.
Honest provenance: generated on 2026-09-02 from AI-assisted analysis of the linked records. See how records are made.