I am using gh bbs2gh to test the migration of our repositories from Bitbucket Server to GitHub Enterprise (GHE). However, the migration script fails with a 401 error at the step where the migrated repository is added to the newly created organization.
I generated the tar file and then used migrate-repo with the required parameters.
The script works correctly when migrating from Bitbucket Server to GitHub.com using the bbs2gh extension, but after setting up GitHub Enterprise Cloud with a data residency subdomain, the process fails with the 401 error.
gh bbs2gh migrate-repo \
--bbs-server-url "${BBS_URL}" \
--bbs-project "${project}" \
--bbs-repo "${repo}" \
gh bbs2gh migrate-repo \
--archive-path "${ARCHIVE_PATH}" \
--github-org "${GITHUB_ORG}" \
--github-repo "${repo}" \
--bbs-server-url "${BBS_URL}" \
--bbs-project "${project}" \
--bbs-repo "${repo}" \
--target-api-url "https://api.XXX.ghe.com" \
--use-github-storage \
--verbose
[2026-02-19 00:59:17] [INFO] You are running an up-to-date version of the bbs2gh extension [v1.26.0]
[2026-02-19 00:59:17] [INFO] BBS SERVER URL: https://bitbucketsandbox.xxxxxx.com
[2026-02-19 00:59:17] [INFO] BBS PROJECT: HUB
[2026-02-19 00:59:17] [INFO] BBS REPO: small-history-repo-github
[2026-02-19 00:59:17] [INFO] SSH PORT: 22
[2026-02-19 00:59:17] [INFO] Export started. Export ID: 165
[2026-02-19 00:59:17] [INFO] Export status: RUNNING; 0% complete
[2026-02-19 00:59:27] [INFO] Export completed. Your migration archive should be ready **on your Bitbucket instance** at $BITBUCKET_SHARED_HOME/data/migration/export/Bitbucket_export_165.tar
Archive path captured for HUB/small-history-repo-github: /data/bitbucketDr/bitbucket_home/shared/data/migration/export/Bitbucket_export_165.tar
[2026-02-19 00:59:28] [INFO] You are running an up-to-date version of the bbs2gh extension [v1.26.0]
[2026-02-19 00:59:28] [INFO] ARCHIVE PATH: /data/bitbucketDr/bitbucket_home/shared/data/migration/export/Bitbucket_export_165.tar
[2026-02-19 00:59:28] [INFO] GITHUB ORG: xx-poc-org
[2026-02-19 00:59:28] [INFO] GITHUB REPO: small-history-repo-github
[2026-02-19 00:59:28] [INFO] TARGET API URL: https://api.xxx.ghe.com
[2026-02-19 00:59:28] [INFO] BBS SERVER URL: https://bitbucketsandbox.xxx.com
[2026-02-19 00:59:28] [INFO] BBS PROJECT: HUB
[2026-02-19 00:59:28] [INFO] BBS REPO: small-history-repo-github
[2026-02-19 00:59:28] [INFO] SSH PORT: 22
[2026-02-19 00:59:28] [INFO] USE GITHUB STORAGE: true
[2026-02-19 00:59:28] [INFO] VERBOSE: true
[2026-02-19 00:59:28] [DEBUG] HTTP GET: https://api.xxx.ghe.com/repos/xxx-poc-org/small-history-repo-github
[2026-02-19 00:59:29] [DEBUG] GITHUB REQUEST ID: 93B6:53B76:CB2A7:11DFACC:6996A6C1
[2026-02-19 00:59:29] [DEBUG] RESPONSE (NotFound): {"message":"Not Found","documentation_url":"https://docs.github.com/rest/repos/repos#get-a-repository","status":"404"}
[2026-02-19 00:59:29] [INFO] Creating Migration Source...
[2026-02-19 00:59:29] [DEBUG] HTTP POST: https://api.xxx.ghe.com/graphql
[2026-02-19 00:59:29] [DEBUG] HTTP BODY: {"query":"query($login: String!) {organization(login: $login) { login, id, name } }","variables":{"login":"xxx-poc-org"}}
[2026-02-19 00:59:29] [DEBUG] GITHUB REQUEST ID: 93B6:53B76:CB2AB:11DFB05:6996A6C1
[2026-02-19 00:59:29] [DEBUG] RESPONSE (OK): {"data":{"organization":{"login":"xxx-poc-org","id":"O_kgDOABIn4A","name":" xxx-poc-org"}}}
[2026-02-19 00:59:29] [DEBUG] HTTP POST: https://api.xxx.ghe.com/graphql
[2026-02-19 00:59:29] [DEBUG] HTTP BODY: {"query":"mutation createMigrationSource($name: String!, $url: String!, $ownerId: ID!, $type: MigrationSourceType!) { createMigrationSource(input: {name: $name, url: $url, ownerId: $ownerId, type: $type}) { migrationSource { id, name, url, type } } }","variables":{"name":"Bitbucket Server Source","url":"https://not-used","ownerId":"O_kgDOABIn4A","type":"BITBUCKET_SERVER"},"operationName":"createMigrationSource"}
[2026-02-19 00:59:31] [DEBUG] GITHUB REQUEST ID: 93B6:53B76:CB2AF:11DFB2D:6996A6C1
[2026-02-19 00:59:31] [DEBUG] RESPONSE (OK): {"data":{"createMigrationSource":{"migrationSource":{"id":"MS_kgDaACQwNDYyNjMzZi0xYWQ3LTQ4ZjctOTE1Ni0zZjI2N2Y4YWU4MDc","name":"Bitbucket Server Source","url":"https://not-used","type":"BITBUCKET_SERVER"}}}}
[2026-02-19 00:59:31] [INFO] Archive path: /data/bitbucketDr/bitbucket_home/shared/data/migration/export/Bitbucket_export_165.tar
[2026-02-19 00:59:31] [DEBUG] HTTP POST: https://api.xxx.ghe.com/graphql
[2026-02-19 00:59:31] [DEBUG] HTTP BODY: {"query":"query($login: String!) {organization(login: $login) { login, databaseId, name } }","variables":{"login":"xxx-poc-org"}}
[2026-02-19 00:59:31] [DEBUG] GITHUB REQUEST ID: 93B6:53B76:CB2D2:11DFCC3:6996A6C3
[2026-02-19 00:59:31] [DEBUG] RESPONSE (OK): {"data":{"organization":{"login":"xxx-poc-org","databaseId":1189856,"name":" xxx-poc-org"}}}
[2026-02-19 00:59:31] [INFO] Uploading archive to GitHub Storage
[2026-02-19 00:59:31] [DEBUG] HTTP POST: https://uploads.github.com/organizations/1189556/gei/archive?name=xa38cf24-7304-4bb9-9157-f64a1cxx92ca19.tar
[2026-02-19 00:59:31] [DEBUG] HTTP BODY: BLOB
[2026-02-19 00:59:32] [DEBUG] GITHUB REQUEST ID: E2B4:3A48D2:2013A6:27E0A5:699xA6C4
[2026-02-19 00:59:32] [DEBUG] RESPONSE (Unauthorized): {"message":"Bad credentials","request_id":"E2B4:3A48D2:2013A6:27E0A5:699xA6C4","documentation_url":"https://docs.github.com/rest"}
[2026-02-19 00:59:32] [DEBUG] [HTTP ERROR 401] System.Net.Http.HttpRequestException: GitHub API error: {"message":"Bad credentials","request_id":"E2B4:3A48D2:2013A6:27E0A5:699xA6C4","documentation_url":"https://docs.github.com/rest"}
---> System.Net.Http.HttpRequestException: Response status code does not indicate success: 401 (Unauthorized).
at System.Net.Http.HttpResponseMessage.EnsureSuccessStatusCode()
at OctoshiftCLI.Services.GithubClient.SendAsync(HttpMethod httpMethod, String url, Object body, HttpStatusCode expectedStatus, Dictionary`2 customHeaders, Int32 retryCount)
--- End of inner exception stack trace ---
at OctoshiftCLI.Services.GithubClient.SendAsync(HttpMethod httpMethod, String url, Object body, HttpStatusCode expectedStatus, Dictionary`2 customHeaders, Int32 retryCount)
at OctoshiftCLI.Services.GithubClient.PostAsync(String url, Object body, Dictionary`2 customHeaders)
at OctoshiftCLI.Services.ArchiveUploader.<>c__DisplayClass10_0.<<Upload>b__0>d.MoveNext()
--- End of stack trace from previous location ---
at Polly.Retry.AsyncRetryEngine.ImplementationAsync[TResult](Func`3 action, Context context, CancellationToken cancellationToken, ExceptionPredicates shouldRetryExceptionPredicates, ResultPredicates`1 shouldRetryResultPredicates, Func`5 onRetryAsync, Int32 permittedRetryCount, IEnumerable`1 sleepDurationsEnumerable, Func`4 sleepDurationProvider, Boolean continueOnCapturedContext)
[2026-02-19 00:59:32] [ERROR] OctoshiftCLI.OctoshiftCliException: Unauthorized. Please check your token and try again
---> System.Net.Http.HttpRequestException: GitHub API error: {"message":"Bad credentials","request_id":"E2B4:3A48D2:2013A6:27E0A5:699xA6C4","documentation_url":"https://docs.github.com/rest"}
---> System.Net.Http.HttpRequestException: Response status code does not indicate success: 401 (Unauthorized).
at System.Net.Http.HttpResponseMessage.EnsureSuccessStatusCode()
at OctoshiftCLI.Services.GithubClient.SendAsync(HttpMethod httpMethod, String url, Object body, HttpStatusCode expectedStatus, Dictionary`2 customHeaders, Int32 retryCount)
--- End of inner exception stack trace ---
at OctoshiftCLI.Services.GithubClient.SendAsync(HttpMethod httpMethod, String url, Object body, HttpStatusCode expectedStatus, Dictionary`2 customHeaders, Int32 retryCount)
at OctoshiftCLI.Services.GithubClient.PostAsync(String url, Object body, Dictionary`2 customHeaders)
at OctoshiftCLI.Services.ArchiveUploader.<>c__DisplayClass10_0.<<Upload>b__0>d.MoveNext()
--- End of stack trace from previous location ---
at Polly.Retry.AsyncRetryEngine.ImplementationAsync[TResult](Func`3 action, Context context, CancellationToken cancellationToken, ExceptionPredicates shouldRetryExceptionPredicates, ResultPredicates`1 shouldRetryResultPredicates, Func`5 onRetryAsync, Int32 permittedRetryCount, IEnumerable`1 sleepDurationsEnumerable, Func`4 sleepDurationProvider, Boolean continueOnCapturedContext)
--- End of inner exception stack trace ---
at OctoshiftCLI.RetryPolicy.<CreateRetryPolicyForException>b__8_1[TException](Exception ex, TimeSpan ts, Context ctx)
at Polly.AsyncRetrySyntax.<>c__DisplayClass22_0.<<WaitAndRetryAsync>b__0>d.MoveNext()
--- End of stack trace from previous location ---
at Polly.Retry.AsyncRetryEngine.ImplementationAsync[TResult](Func`3 action, Context context, CancellationToken cancellationToken, ExceptionPredicates shouldRetryExceptionPredicates, ResultPredicates`1 shouldRetryResultPredicates, Func`5 onRetryAsync, Int32 permittedRetryCount, IEnumerable`1 sleepDurationsEnumerable, Func`4 sleepDurationProvider, Boolean continueOnCapturedContext)
at Polly.AsyncPolicy.ExecuteAsync[TResult](Func`3 action, Context context, CancellationToken cancellationToken, Boolean continueOnCapturedContext)
at OctoshiftCLI.RetryPolicy.Retry[T](Func`1 func)
at OctoshiftCLI.Services.ArchiveUploader.Upload(Stream archiveContent, String archiveName, String orgDatabaseId)
at OctoshiftCLI.Services.GithubApi.UploadArchiveToGithubStorage(String orgDatabaseId, String archiveName, Stream archiveContent)
at OctoshiftCLI.BbsToGithub.Commands.MigrateRepo.MigrateRepoCommandHandler.UploadArchiveToGithub(String org, String archivePath)
at OctoshiftCLI.BbsToGithub.Commands.MigrateRepo.MigrateRepoCommandHandler.UploadArchiveToGithub(String org, String archivePath)
at OctoshiftCLI.BbsToGithub.Commands.MigrateRepo.MigrateRepoCommandHandler.Handle(MigrateRepoCommandArgs args)
at OctoshiftCLI.Extensions.CommandExtensions.RunHandler[TArgs,THandler](TArgs args, ServiceProvider sp, CommandBase`2 command)
at OctoshiftCLI.Extensions.CommandExtensions.<>c__DisplayClass1_0`3.<<ConfigureCommand>b__0>d.MoveNext()
--- End of stack trace from previous location ---
at System.CommandLine.Invocation.AnonymousCommandHandler.InvokeAsync(InvocationContext)
at System.CommandLine.Invocation.InvocationPipeline.<>c__DisplayClass4_0.<<BuildInvocationChain>b__0>d.MoveNext()
--- End of stack trace from previous location ---
at System.CommandLine.Builder.CommandLineBuilderExtensions.<>c__DisplayClass17_0.<<UseParseErrorReporting>b__0>d.MoveNext()
--- End of stack trace from previous location ---
at System.CommandLine.Builder.CommandLineBuilderExtensions.<>c__DisplayClass12_0.<<UseHelp>b__0>d.MoveNext()
--- End of stack trace from previous location ---
at System.CommandLine.Builder.CommandLineBuilderExtensions.<>c__DisplayClass22_0.<<UseVersionOption>b__0>d.MoveNext()
--- End of stack trace from previous location ---
at System.CommandLine.Builder.CommandLineBuilderExtensions.<>c__DisplayClass19_0.<<UseTypoCorrections>b__0>d.MoveNext()
--- End of stack trace from previous location ---
at System.CommandLine.Builder.CommandLineBuilderExtensions.<>c.<<UseSuggestDirective>b__18_0>d.MoveNext()
--- End of stack trace from previous location ---
at System.CommandLine.Builder.CommandLineBuilderExtensions.<>c__DisplayClass16_0.<<UseParseDirective>b__0>d.MoveNext()
--- End of stack trace from previous location ---
at System.CommandLine.Builder.CommandLineBuilderExtensions.<>c.<<RegisterWithDotnetSuggest>b__5_0>d.MoveNext()
--- End of stack trace from previous location ---
at System.CommandLine.Builder.CommandLineBuilderExtensions.<>c__DisplayClass8_0.<<UseExceptionHandler>b__0>d.MoveNext()
Based on the verbose output, it seems that this command doesn't use the --target-api-url parameter and is calling the api.github.com instead api.xxx.ghe.com. It is needed to extend it in same way as done in.
I am using gh bbs2gh to test the migration of our repositories from Bitbucket Server to GitHub Enterprise (GHE). However, the migration script fails with a 401 error at the step where the migrated repository is added to the newly created organization.
I generated the tar file and then used migrate-repo with the required parameters.
The script works correctly when migrating from Bitbucket Server to GitHub.com using the bbs2gh extension, but after setting up GitHub Enterprise Cloud with a data residency subdomain, the process fails with the 401 error.
We have followed below steps:
1) Create classic token with required migration permission and authenticate token with SSO.
2) Generate Archive using below command
3) Migrate Generated Archive to Github with use of --use-github-storage
I get this output:
Based on the verbose output, it seems that this command doesn't use the --target-api-url parameter and is calling the api.github.com instead api.xxx.ghe.com. It is needed to extend it in same way as done in.
Note:
I am using xxx.ghe.com as target (GitHub with data residency).