Skip to content

certgen: std::fs::rename fails with EXDEV on WSL/container cross-device mounts #2173

Description

@rsandbach

Agent Diagnostic

Can't use an agent if I can't setup a gateway. :-D (I had GitHub copilot start drafting this issue, after working out why the cross device failure was happening)

When generating cert files, crates/openshell-server/src/certgen.rs uses std::fs::rename(...) to move the newly generated certificates to the specified output directory. In some cases, the source and destination can land on different mounts/devices. In that case, rename(2) returns EXDEV (Rust: std::io::ErrorKind::CrossesDevices), which causes cert generation to fail.

Due to the location the temporary files are created, ${output_dir}.certgen.tmp, they are actually being created on the container's tempfs, not the attached volume. This can lead to the cross devices error.

Workaround (set --output-dir to a new folder within the mounted volume)

PS C:\> container run --rm -it -u 0:0 -v ogc:/extvol ghcr.io/nvidia/openshell/gateway:latest generate-certs --output-dir "/extvol/z"
2026-07-08T03:31:06.530744Z  INFO openshell_server::certgen: PKI files created. dir=/extvol/z

Expected

Cert generation should succeed regardless of whether source/destination are on the same device.
The temp certs probably should get created IN the --output-dir, not next to it.

Actual

Move step fails with cross-device rename error (EXDEV / CrossesDevices).

Proposed fix

Use a cross-device-safe move:

  1. Attempt std::fs::rename(src, dst) first.
  2. On ErrorKind::CrossesDevices, fallback to:
    • std::fs::copy(src, dst)
    • preserve permissions if needed
    • std::fs::remove_file(src)
  3. Propagate all other errors unchanged.

OR

Generate the temporary certificates within a folder of the output dir (/extvol/certgen.tmp/ca.crt), not in it.

Why this change

This preserves same-device fast path/behavior while handling common WSL/container mount layouts where cross-device moves are expected.

Description

generate-certs fails with --output-dir args.
generate-certs to be successful.

Reproduction Steps

Environment

  • Windows host + WSLC
PS C:\> container run --rm -it -u 0:0 -v ogc:/extvol ghcr.io/nvidia/openshell/gateway:latest generate-certs --output-dir "/extvol"
Error:   x failed to move /extvol.certgen.tmp/ca.crt -> /extvol/ca.crt
  `-> Invalid cross-device link (os error 18)

Environment

Windows 11 25H2
wslc 2.9.3.0

Logs

Error:   x failed to move /extvol.certgen.tmp/ca.crt -> /extvol/ca.crt
  `-> Invalid cross-device link (os error 18)

Agent-First Checklist

  • I pointed my agent at the repo and had it investigate this issue
  • I loaded relevant skills (e.g., debug-openshell-cluster, debug-inference, openshell-cli)
  • My agent could not resolve this — the diagnostic above explains why

Metadata

Metadata

Assignees

No one assigned

    Labels

    state:triage-neededOpened without agent diagnostics and needs triage

    Type

    Fields

    No fields configured for Bug.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions