Skip to main content

Troubleshooting

Common issues and their fixes. Each section links to the relevant reference page for deeper context.

Authentication and login

Password reset email not arriving

Check your spam folder. Password reset emails come from hello@frem.sh. If your org uses SSO, password reset is not the right path. Use the Sign in with <IdP> button on the login page instead. SSO accounts may not have a local password set.

SSO login fails with redirect_uri mismatch

The IdP rejected the callback because the redirect URI registered there doesn’t exactly match what fremforge sends. Copy the exact redirect URI from Org admin → SSO → <auth source> → Details and do not type it manually. A single trailing slash difference causes this error. See OIDC single sign-on.

SSH: Permission denied (publickey)

Three common causes:

  • The key has not been added to your fremforge account (User settings → SSH / GPG Keys → Add key).
  • The key file referenced by your SSH client belongs to a different user account.
  • The key format is unsupported (Ed25519, RSA 3072+, and ECDSA are supported; DSA keys are rejected).

Test your key: ssh -T -p 443 git@ssh.frem.sh, fremforge exposes SSH on port 443 via ssh.frem.sh (port 22 isn’t open). A successful auth returns Hi <username>! You've successfully authenticated.... See Getting started for key setup and Connecting for the ~/.ssh/config Host alias that lets you keep writing git@frem.sh in your remotes.

PAT expired / 401 on API calls

PATs expire after 90 days, which is also the maximum (ttl_days accepts 1-90). Check:

  1. The token is still listed under User settings → Applications.
  2. The token has the required scope. Control-plane REST calls use the fremforge scope vocabulary (orgs:read, findings:read, …) — see API tokens. Package registries take no PAT at all; see Packages / Registry below.
  3. The token value was copied correctly (it is shown only once at creation).

Generate a new token if in doubt.

CI / Runners

Job stuck in queue

The org is guaranteed 2 concurrent jobs per seat (at least 10, at most 60), and can use up to 60 while the platform has spare capacity. A trial org runs 2 at a time. Check how many jobs are currently running at frem.sh/<org>/_admin/billing. If all of the org’s slots are occupied, jobs wait in the queue until a slot opens. They are not cancelled.

If the queue is empty but jobs are still stuck, the runner agent may be offline. Check runner status at Org admin → Runners.

actions/checkout fails: repository not found

The built-in FORGEJO_TOKEN needs contents: read permission. Add a permissions: block to the job or workflow:

permissions:
  contents: read

If the repository is private and the token is a PAT rather than the built-in token, verify the PAT has repo scope.

Secret is set but shows as empty in the job

The secret is set at the wrong scope. Secrets follow this precedence: environment secret → repo secret → org secret. If your job declares environment: production, only secrets set on that environment (and repo/org secrets not shadowed by it) are injected. Check that the secret is set at the scope that matches the job’s environment: declaration.

Docker: Cannot connect to the Docker daemon

fremforge runners are ephemeral VMs, one per commit (debian 13) with a native Docker daemon pre-installed. docker build, docker run, and docker/build-push-action@v5 all work without extra setup. If you see this error, check that the job declares runs-on: fremforge (so it lands on a fremforge runner rather than a self-hosted label without Docker):

jobs:
  build-image:
    runs-on: fremforge
    steps:
      - uses: actions/checkout@v4
      - uses: docker/setup-buildx-action@v3
      - uses: docker/build-push-action@v5
        with:
          context: .
          push: true
          tags: registry.example.com/${{ github.repository }}:${{ github.sha }}

For pure image copy/retag/push between registries, skopeo is pre-installed. See CI runners for available runner labels and docs.frem.sh/build/actions/runner-image/ for the full pre-installed tooling list.

upload-artifact retries on 413, then fails with Status Code: 413

The organisation’s Actions artifact quota (5 GiB per seat) is full. The step log shows A 413 status code has been received, will attempt to retry the upload several times, then Status Code: 413 and Status Message: Request Entity Too Large. Retrying the job does not help until space is freed. See Actions artifacts and attachments.

Action not found: uses: some/action@v1

Most GitHub Marketplace actions work on fremforge. Actions that call github.com/api/v3 directly will fail because they target the GitHub API, not the fremforge API. Check Marketplace compatibility for the per-action compatibility matrix.

Git and repositories

Push rejected: secret detected

Gitleaks (pre-receive hook) blocked the push because a secret pattern was detected in the commit. The push was not accepted. The secret never reached the repository.

Steps to resolve:

  1. Rotate the secret immediately in the system that issued it, even if the push was rejected. Assume the value is compromised from the moment it appeared in your working tree.
  2. Remove the secret from your working tree and commit history using git filter-repo.
  3. Re-push the cleaned history.

See Security and supply chain for details on what patterns are detected.

Push rejected: branch protection

A branch protection rule is blocking the push. Check the rules under Repo Settings → Branches → <branch name>. Common causes: a required status check hasn’t passed, force-push is disabled, or the push requires a signed commit.

LFS: batch request failed

LFS must be enabled per-repo. Enable it under Repo Settings → Git LFS → Enable. If LFS is enabled and the error persists, check the org storage quota. LFS storage counts toward the 5 GB/seat LFS pool, which is separate from the 5 GB/seat package registry pool.

Webhooks

Webhook not firing

Check recent delivery attempts at Repo Settings → Webhooks → <webhook> → Recent deliveries. The most common cause is the payload URL being unreachable from fremforge’s T Cloud Public egress IPs. If deliveries show as failed, the response body typically includes the HTTP status returned by your endpoint. See Webhooks for egress IP ranges.

Webhook fires but payload is wrong

Verify which event types are subscribed. A push to a tag sends a push event, not a create event. Check the Events configuration on the webhook. See Webhooks for the full event vocabulary.

SSO / SCIM

SCIM user provisioned but cannot log in

Domain verification is required before SCIM-provisioned users can authenticate. Verify the email domain under Org admin → SSO → Verified domains. The domain in the user’s email address must appear there.

Packages / Registry

Registries accept two credentials only: the automatic token of a Forgejo Actions job, and the short-lived token the fremforge CLI hands your tools. API tokens (ffp_…) are refused. See Package registry → Authentication.

Actions job: 403 this job's token can only write packages linked to its own repository

The job tried to publish a package that belongs to another repository of the org, or one that is linked to no repository. A job’s token writes only packages linked to its own repository, and new packages it creates. Publish from the repository the package belongs to, or link an unlinked package to this repository on the package’s Settings page.

Actions job: 401 or 403 on publish from a pull request

Runs for pull requests from forks get read access only. Publish from a push or tag workflow in the repository itself.

docker pull or push: unauthorized

On your machine, check the CLI sign-in and the helper:

fremforge auth status
printf 'frem.sh\n' | docker-credential-fremforge get    # prints JSON when the helper works
  • not logged in → run fremforge auth login.
  • docker-credential-fremforge: command not found → the helper’s directory (~/.local/bin) is not on your PATH, or fremforge auth configure docker was never run.
  • fremforge manages frem.sh registry credentials after docker login frem.sh → expected; the helper refuses stored passwords. Use fremforge auth login.

npm, Maven or Gradle: 401 after a while

These tools read a copy of the token from their config file, and that copy expires after at most an hour. Run any fremforge command, or fremforge auth refresh, to rewrite it. Add "preinstall": "fremforge auth refresh --quiet" to package.json, or a pre-build step in your IDE, so builds always start with a fresh token.

pip or uv: 401 or a password prompt

pip and uv only ask keyring when told to: pip config set global.keyring-provider subprocess, or UV_KEYRING_PROVIDER=subprocess for uv. The index URL must carry your username (https://<username>@frem.sh/api/packages/<org>/pypi/simple/). Check that the keyring in ~/.local/bin comes first on your PATH: command -v keyring.

Org slug and name availability

Org slugs must be 3-30 characters, lowercase, letters/digits/hyphens only, no leading or trailing hyphens.

If a slug shows as unavailable during signup: it is either registered by another org or on the reserved-names list. The reserved list covers common role names (admin, api, billing, support, status, security, abuse, root, system, fremforge, and similar) to prevent phishing or service-path collisions.

Trademark-adjacent names (e.g., slugs that closely resemble well-known brand names) enter a soft-review queue instead of being immediately blocked. If your signup is in the queue, you receive an email from support@frem.sh within one business day. In most cases, legitimate companies using their own brand name are approved without friction.

If your preferred slug is taken by an inactive or squatting org, contact support@frem.sh. Include the desired slug and your org’s domain or other ownership evidence. Slug transfers are handled case-by-case.

Changing your org slug after creation: Org admin → Settings → Rename organization. All existing repository URLs, clone URLs, and API calls using the old slug continue to redirect for 90 days. After 90 days the old slug becomes available for registration.

Cross-references