[Bug] headscale generate private-key requires a config.yaml file (even if empty) #1071

Closed
opened 2025-12-29 02:28:06 +01:00 by adam · 2 comments
Owner

Originally created by @lucasfcnunes on GitHub (Jul 25, 2025).

Is this a support request?

  • This is not a support request

Is there an existing issue for this?

  • I have searched the existing issues

Current Behavior

Fatal error when generating private-keys without a config.yaml. An empty file makes it work.

Expected Behavior

Generate a private-keys without the need of an existing config.yaml file.

Steps To Reproduce

# compose.yaml
services:
  headscale:
    build:
      dockerfile_inline: |
        ARG HEADSCALE_VERSION

        FROM ghcr.io/juanfont/headscale:$${HEADSCALE_VERSION} AS headscale

        FROM busybox AS with-config
        COPY --from=headscale /ko-app/headscale /usr/local/bin/headscale
      args:
        HEADSCALE_VERSION: 0.26.1
    entrypoint: ''
    environment:
      CONFIG_FILE: "/etc/headscale/config.yaml"
      CMD: "headscale generate private-key"
    command:
      - sh
      - -c
      - |
        set -x

        echo "Without config file"
        $${CMD}

        echo "With (empty) config file"
        mkdir -p $(dirname $${CONFIG_FILE})
        echo "" > $${CONFIG_FILE} && $${CMD}

$ docker compose run --build --rm headscale
WARN[0000] Found orphan containers ([lucasfcnunes_incentive-me-monorepo]) for this project. If you removed or renamed this service in your compose file, you can run this command with the --remove-orphans flag to clean it up. 
[+] Building 0.9s (10/10) FINISHED                                                                                                                                                               
 => [internal] load local bake definitions                                                                                                                                                  0.0s
 => => reading from stdin 793B                                                                                                                                                              0.0s
 => [internal] load build definition from Dockerfile                                                                                                                                        0.0s
 => => transferring dockerfile: 359B                                                                                                                                                        0.0s
 => WARN: InvalidDefaultArgInFrom: Default value for ARG ghcr.io/juanfont/headscale:${HEADSCALE_VERSION} results in empty or invalid base image name (line 3)                               0.0s
 => [internal] load metadata for docker.io/library/busybox:latest                                                                                                                           0.0s
 => [internal] load metadata for ghcr.io/juanfont/headscale:0.26.1                                                                                                                          0.0s
 => [internal] load .dockerignore                                                                                                                                                           0.0s
 => => transferring context: 2B                                                                                                                                                             0.0s
 => [headscale 1/1] FROM ghcr.io/juanfont/headscale:0.26.1@sha256:ea9b5ee06274d757a4d52103de56cd11a9c393acb19d9a35f4b9fe52ada410de                                                          0.0s
 => => resolve ghcr.io/juanfont/headscale:0.26.1@sha256:ea9b5ee06274d757a4d52103de56cd11a9c393acb19d9a35f4b9fe52ada410de                                                                    0.0s
 => [with-config 1/2] FROM docker.io/library/busybox:latest@sha256:f85340bf132ae937d2c2a763b8335c9bab35d6e8293f70f606b9c6178d84f42b                                                         0.0s
 => => resolve docker.io/library/busybox:latest@sha256:f85340bf132ae937d2c2a763b8335c9bab35d6e8293f70f606b9c6178d84f42b                                                                     0.0s
 => CACHED [with-config 2/2] COPY --from=headscale /ko-app/headscale /usr/local/bin/headscale                                                                                               0.0s
 => exporting to image                                                                                                                                                                      0.2s
 => => exporting layers                                                                                                                                                                     0.0s
 => => exporting manifest sha256:2b6e2d7ff261d2ddb3c716d37d5368f5d9c2ff43d468cfd8f002d297588fad33                                                                                           0.0s
 => => exporting config sha256:a014f2f0bbb51f63b4b303fd333aa30a2b50cc6798f55d3f2c7a6780e7966586                                                                                             0.0s
 => => exporting attestation manifest sha256:60952a04b42b9d94e7c1412cdd55467504ecadc1db896b2d9b480bf998af0b10                                                                               0.0s
 => => exporting manifest list sha256:e1e218270cd903e5fdfad433a2dfbe737245312c0645061f54ea7618f8229814                                                                                      0.0s
 => => naming to docker.io/library/lucasfcnunes_incentive-me-headscale:latest                                                                                                               0.0s
 => => unpacking to docker.io/library/lucasfcnunes_incentive-me-headscale:latest                                                                                                            0.0s
 => resolving provenance for metadata file                                                                                                                                                  0.0s


+ echo 'Without config file'
Without config file
+ headscale generate private-key
2025-07-25T01:04:09Z FTL home/runner/work/headscale/headscale/cmd/headscale/cli/root.go:55 > Error loading config error="fatal error reading config file: Config File \"config\" Not Found in \"[/etc/headscale /root/.headscale /]\""


+ echo 'With (empty) config file'
With (empty) config file
+ dirname /etc/headscale/config.yaml
+ mkdir -p /etc/headscale
+ echo 
+ headscale generate private-key
privkey:30ac3f1f32fafbbead4a68708c8a123b916b3bdea1c1fc3fcc1838aca2a31968

Environment

- OS: Linux Ubuntu 22.04.5 LTS
- Headscale version: 0.26.1
- Tailscale version: NA

Runtime environment

  • Headscale is behind a (reverse) proxy
  • Headscale runs in a container

Debug information

NA

Originally created by @lucasfcnunes on GitHub (Jul 25, 2025). ### Is this a support request? - [x] This is not a support request ### Is there an existing issue for this? - [x] I have searched the existing issues ### Current Behavior Fatal error when generating private-keys without a `config.yaml`. An empty file makes it work. ### Expected Behavior Generate a private-keys without the need of an existing `config.yaml` file. ### Steps To Reproduce ```yaml # compose.yaml services: headscale: build: dockerfile_inline: | ARG HEADSCALE_VERSION FROM ghcr.io/juanfont/headscale:$${HEADSCALE_VERSION} AS headscale FROM busybox AS with-config COPY --from=headscale /ko-app/headscale /usr/local/bin/headscale args: HEADSCALE_VERSION: 0.26.1 entrypoint: '' environment: CONFIG_FILE: "/etc/headscale/config.yaml" CMD: "headscale generate private-key" command: - sh - -c - | set -x echo "Without config file" $${CMD} echo "With (empty) config file" mkdir -p $(dirname $${CONFIG_FILE}) echo "" > $${CONFIG_FILE} && $${CMD} ``` ```console $ docker compose run --build --rm headscale WARN[0000] Found orphan containers ([lucasfcnunes_incentive-me-monorepo]) for this project. If you removed or renamed this service in your compose file, you can run this command with the --remove-orphans flag to clean it up. [+] Building 0.9s (10/10) FINISHED => [internal] load local bake definitions 0.0s => => reading from stdin 793B 0.0s => [internal] load build definition from Dockerfile 0.0s => => transferring dockerfile: 359B 0.0s => WARN: InvalidDefaultArgInFrom: Default value for ARG ghcr.io/juanfont/headscale:${HEADSCALE_VERSION} results in empty or invalid base image name (line 3) 0.0s => [internal] load metadata for docker.io/library/busybox:latest 0.0s => [internal] load metadata for ghcr.io/juanfont/headscale:0.26.1 0.0s => [internal] load .dockerignore 0.0s => => transferring context: 2B 0.0s => [headscale 1/1] FROM ghcr.io/juanfont/headscale:0.26.1@sha256:ea9b5ee06274d757a4d52103de56cd11a9c393acb19d9a35f4b9fe52ada410de 0.0s => => resolve ghcr.io/juanfont/headscale:0.26.1@sha256:ea9b5ee06274d757a4d52103de56cd11a9c393acb19d9a35f4b9fe52ada410de 0.0s => [with-config 1/2] FROM docker.io/library/busybox:latest@sha256:f85340bf132ae937d2c2a763b8335c9bab35d6e8293f70f606b9c6178d84f42b 0.0s => => resolve docker.io/library/busybox:latest@sha256:f85340bf132ae937d2c2a763b8335c9bab35d6e8293f70f606b9c6178d84f42b 0.0s => CACHED [with-config 2/2] COPY --from=headscale /ko-app/headscale /usr/local/bin/headscale 0.0s => exporting to image 0.2s => => exporting layers 0.0s => => exporting manifest sha256:2b6e2d7ff261d2ddb3c716d37d5368f5d9c2ff43d468cfd8f002d297588fad33 0.0s => => exporting config sha256:a014f2f0bbb51f63b4b303fd333aa30a2b50cc6798f55d3f2c7a6780e7966586 0.0s => => exporting attestation manifest sha256:60952a04b42b9d94e7c1412cdd55467504ecadc1db896b2d9b480bf998af0b10 0.0s => => exporting manifest list sha256:e1e218270cd903e5fdfad433a2dfbe737245312c0645061f54ea7618f8229814 0.0s => => naming to docker.io/library/lucasfcnunes_incentive-me-headscale:latest 0.0s => => unpacking to docker.io/library/lucasfcnunes_incentive-me-headscale:latest 0.0s => resolving provenance for metadata file 0.0s + echo 'Without config file' Without config file + headscale generate private-key 2025-07-25T01:04:09Z FTL home/runner/work/headscale/headscale/cmd/headscale/cli/root.go:55 > Error loading config error="fatal error reading config file: Config File \"config\" Not Found in \"[/etc/headscale /root/.headscale /]\"" + echo 'With (empty) config file' With (empty) config file + dirname /etc/headscale/config.yaml + mkdir -p /etc/headscale + echo + headscale generate private-key privkey:30ac3f1f32fafbbead4a68708c8a123b916b3bdea1c1fc3fcc1838aca2a31968 ``` ### Environment ```markdown - OS: Linux Ubuntu 22.04.5 LTS - Headscale version: 0.26.1 - Tailscale version: NA ``` ### Runtime environment - [ ] Headscale is behind a (reverse) proxy - [x] Headscale runs in a container ### Debug information NA
adam added the bug label 2025-12-29 02:28:06 +01:00
adam closed this issue 2025-12-29 02:28:06 +01:00
Author
Owner

@nblock commented on GitHub (Jul 25, 2025):

#2193 is somewhat related. An empty configuration file is required for the remote CLI even if all required configuration settings are provided as environment variables.

@nblock commented on GitHub (Jul 25, 2025): #2193 is somewhat related. An empty configuration file is required for the remote CLI even if all required configuration settings are provided as environment variables.
Author
Owner

@nblock commented on GitHub (Oct 19, 2025):

Fixed in main via c97d0ff23d

@nblock commented on GitHub (Oct 19, 2025): Fixed in main via c97d0ff23dd86492bcb6c9e31339527e4651129a
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: starred/headscale#1071