cloudflare/cloudflared · error

could not write token to configuration directory: %w

Error message

could not write token to configuration directory: %w

What it means

When `cloudflared service install <token>` is used on macOS, installLaunchd writes the tunnel token to a file inside the Application Support config directory via writeTokenToConfigDir. This error wraps any failure of that write, which covers both creating the directory and writing the token file. A deferred cleanup removes the token file so a failed install leaves no secrets behind.

Source

Thrown at cmd/cloudflared/macos_service.go:185

		// shadow the outer one, causing the defer below to not have access to
		// the outer err
		var cp string
		cp, err = configPath()
		if err != nil {
			log.Err(err).Msg("Error determining path to config directory")
			return err
		}

		// Ensure token file is removed if install fails at any point from now
		// on
		defer func() {
			if err != nil {
				removeTokenFile(cp, log)
			}
		}()

		if err = writeTokenToConfigDir(c, cp); err != nil {
			return fmt.Errorf("could not write token to configuration directory: %w", err)
		}

		extraArgs = buildArgsForTokenFile(cp)
	}

	stdoutPath, err := stdoutPath()
	if err != nil {
		log.Err(err).Msg("error determining stdout path")
		return errors.Wrap(err, "error determining stdout path")
	}
	stderrPath, err := stderrPath()
	if err != nil {
		log.Err(err).Msg("error determining stderr path")
		return errors.Wrap(err, "error determining stderr path")
	}
	launchdTemplate := newLaunchdTemplate(installPath, stdoutPath, stderrPath)
	templateArgs := ServiceTemplateArgs{Path: etPath, ExtraArgs: extraArgs}
	err = launchdTemplate.Generate(&templateArgs)

View on GitHub (pinned to 2253eeeb25)

Solutions

  1. Check the wrapped error for permission denied and fix ownership/permissions on ~/Library/Application Support (or the root user's equivalent when installing as root)
  2. Verify the disk is not full and the volume is writable
  3. Ensure the HOME of the executing user resolves correctly (sudo may change HOME; use `sudo -H` if needed)
  4. Retry the install; on failure the token file is auto-removed, so no stale token should block a retry
  5. As a workaround, install without a token and use a config file instead

Example fix

// before (fails when HOME is wrong under sudo)
sudo cloudflared service install <token>

// after (preserves user's writable HOME)
sudo -H cloudflared service install <token>
Defensive patterns

Strategy: validation

Validate before calling

// Go: pre-check config dir writability before install
func configDirWritable(dir string) error {
    if err := os.MkdirAll(dir, 0o700); err != nil { return err }
    probe := filepath.Join(dir, ".probe")
    if err := os.WriteFile(probe, []byte("ok"), 0o600); err != nil { return err }
    return os.Remove(probe)
}

Try / catch

if err := writeTokenToConfigDir(c, cp); err != nil {
    if errors.Is(err, fs.ErrPermission) {
        log.Printf("cannot write token to %s: check ownership/permissions or use sudo -H", cp)
    }
    return fmt.Errorf("could not write token to configuration directory: %w", err)
}

Prevention

When it happens

Trigger: Running `cloudflared service install <token>` on macOS when writeTokenToConfigDir fails: the Application Support directory cannot be created (permission denied, read-only volume, disk full), or the token file cannot be written/created.

Common situations: Installing as a user whose ~/Library/Application Support is not writable; running under sudo with a sandboxed/restricted HOME; full disk; corporate MDM policies blocking writes to Application Support.

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 cloudflare/cloudflared@2253eeeb25 (2026-09-06). Data as JSON: /api/errors/48a27fcf897dccb4. Report an issue: GitHub.