phacility/phabricator · error · Exception

This repository is read-only over SSH (tried to execute prot

Error message

This repository is read-only over SSH (tried to execute protocol command "%s").

What it means

requireWriteAccess() asks canServeProtocol(BUILTIN_PROTOCOL_SSH, true) whether any repository URI serves writes over SSH. When that returns false but the SSH request carried a recognized write protocol command (e.g. git-receive-pack), this exception names the offending command. The repository's SSH serving configuration is read-only - it is not a user-permission problem.

Source

Thrown at src/applications/diffusion/ssh/DiffusionSSHWorkflow.php:288

    }

    if ($repository->isReadOnly()) {
      throw new Exception($repository->getReadOnlyMessageForDisplay());
    }

    $protocol = PhabricatorRepositoryURI::BUILTIN_PROTOCOL_SSH;
    if ($repository->canServeProtocol($protocol, true)) {
      $can_push = PhabricatorPolicyFilter::hasCapability(
        $viewer,
        $repository,
        DiffusionPushCapability::CAPABILITY);
      if (!$can_push) {
        throw new Exception(
          pht('You do not have permission to push to this repository.'));
      }
    } else {
      if ($protocol_command !== null) {
        throw new Exception(
          pht(
            'This repository is read-only over SSH (tried to execute '.
            'protocol command "%s").',
            $protocol_command));
      } else {
        throw new Exception(
          pht('This repository is read-only over SSH.'));
      }
    }

    $this->hasWriteAccess = true;
    return $this->hasWriteAccess;
  }

  protected function shouldSkipReadSynchronization() {
    $viewer = $this->getSSHUser();

    // Currently, the only case where devices interact over SSH without

View on GitHub (pinned to 5720a38cfe)

Solutions

  1. Repository -> Manage URIs: edit the builtin SSH URI and set 'Serve Over SSH' to 'Read/Write', then retry
  2. If SSH writes are intentionally disabled, push over the protocol that does serve writes (usually HTTP)
  3. Check which URI clients actually use - a custom ssh:// URI may be marked observe-only while another is the intended push target
Defensive patterns

Strategy: validation

Validate before calling

if (!$repository->canServeProtocol(
      PhabricatorRepositoryURI::BUILTIN_PROTOCOL_SSH,
      true)) {
  // refuse the write before launching the client session
}

Prevention

When it happens

Trigger: git push over SSH while the repository's builtin SSH URI has 'Serve Over SSH' set to 'Read Only' or 'Off'; mercurial push over ssh:// against a repository whose SSH URI only serves reads.

Common situations: New repositories created with SSH write serving disabled; admins disabling SSH pushes in favor of HTTP; URI table edited during hosting changes and write serving never restored.

Related errors


AI-assisted analysis of phacility/phabricator@5720a38cfe (2026-08-21). Data as JSON: /api/errors/c5f03d76e7062c30. Report an issue: GitHub.