{"record":{"id":"c6bd6388c09ab33d","repo":"phacility/phabricator","slug":"client-transmitted-more-than-1mb-of-data-without-t","errorCode":null,"errorMessage":"Client transmitted more than 1MB of data without transmitting a recognizable protocol frame.","messagePattern":"Client transmitted more than 1MB of data without transmitting a recognizable protocol frame\\.","errorType":"exception","errorClass":"Exception","httpStatus":null,"severity":"error","filePath":"src/applications/diffusion/ssh/DiffusionSubversionServeSSHWorkflow.php","lineNumber":100,"sourceCode":"\n      if (!$exec_channel->isOpenForReading()) {\n        throw new Exception(\n          pht(\n            '%s subprocess exited before emitting a protocol frame.',\n            'svnserve'));\n      }\n    }\n\n    $io_protocol = new DiffusionSubversionWireProtocol();\n    while (true) {\n      PhutilChannel::waitForAny(array($io_channel));\n      $io_channel->update();\n\n      $in_message = $io_channel->read();\n      if ($in_message !== null) {\n        $this->peekBuffer .= $in_message;\n        if (strlen($this->peekBuffer) > (1024 * 1024)) {\n          throw new Exception(\n            pht(\n              'Client transmitted more than 1MB of data without transmitting '.\n              'a recognizable protocol frame.'));\n        }\n\n        $messages = $io_protocol->writeData($in_message);\n        if ($messages) {\n          $message = head($messages);\n          $struct = $message['structure'];\n\n          // This is the:\n          //\n          //   ( version ( cap1 ... ) url ... )\n          //\n          // The `url` allows us to identify the repository.\n\n          $uri = $struct[2]['value'];\n          $path = $this->getPathFromSubversionURI($uri);","sourceCodeStart":82,"sourceCodeEnd":118,"githubUrl":"https://github.com/phacility/phabricator/blob/5720a38cfe95b00ca4be5016dd0d2f3195f4fa04/src/applications/diffusion/ssh/DiffusionSubversionServeSSHWorkflow.php#L82-L118","documentation":"While peeking at the first ra_svn frame, the workflow accumulates raw client bytes in peekBuffer; if it exceeds 1MiB without DiffusionSubversionWireProtocol yielding a parseable frame, the connection is cut. The guard bounds memory against garbage input and doubles as a compatibility check - a client speaking something the parser does not recognize trips it.","triggerScenarios":"A non-SVN or incompatible SVN client opens svn+ssh to the Phabricator SSH endpoint; a tunnel wrapper corrupts stdin so the byte stream never parses; deliberately oversized junk streamed at the endpoint.","commonSituations":"Users pointing tools other than svn at the Phabricator SSH user; SVN client versions far newer than the supported ra_svn dialect; ssh ProxyCommand setups that mangle the channel.","solutions":["Connect with a compatible svn client over svn+ssh:// with no extra tunnel rewriting","Reproduce with 'svn ls svn+ssh://user@host/REPO' from the same machine to isolate client configuration","Remove custom tunnel definitions in ~/.subversion/config that alter the command or the stream"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try {\n  $workflow->executeRepositoryOperations();\n} catch (Exception $ex) {\n  // The 1MB guard is terminal for the session: log, close the channel,\n  // and report to the client - do not retry with the same stream.\n  phlog($ex);\n  $io_channel->closeForRead();\n  $io_channel->closeForWrite();\n}","preventionTips":["Treat this error as terminal for the session - retrying with the same client config reproduces it","When building custom SVN tooling, parse frames incrementally client-side instead of streaming raw blobs"],"tags":["phabricator","svn","ra-svn","protocol","input-validation","limits"],"backgroundTag":"protocol-parse-error","analyzedSha":"5720a38cfe95b00ca4be5016dd0d2f3195f4fa04","analyzedAt":"2026-08-21T05:07:25.672Z","schemaVersion":2},"datasetVersion":"2026-08-21T11:28:35.574Z"}