Move an AWS Account to Another Organization
How to move an AWS account to another organization: invite it from the destination, enroll it in Control Tower, then fix sign-on, guardrails and old roles.
When you need to move an AWS account to another organization, the move itself takes minutes. Getting the account governed afterwards is the real work. In a multi-account AWS governance engagement, I worked on exactly this: production accounts that had to end up under the destination's AWS Control Tower, reachable by the same people, and inside the destination's own guardrails.
Done casually, a move looks finished long before it is. The account shows up in the new organization, the Control Tower dashboard says enrolled, and people sign in through the new portal. Meanwhile the old organization can still administer the account, and your own guardrail policies may not reach it at all. Nothing on the screen tells you either of those things.
The right route is to invite the account from the destination organization's management account. When it accepts, AWS moves it across directly: it never leaves its old organization by itself and never runs standalone in between. The older leave-then-join route is the one that produces this error, and you don't need to fix it:
The member account is missing one or more of the prerequisites required to operate as a standalone account. To add what is missing, sign-in to the member account using the AWS Organizations console, then select to leave the organization...
What follows is the order of operations that works with Control Tower, and the three checks that decide whether a moved account is actually governed: sign-on, your own guardrail policies, and the old organization's admin role. On those moves, the client's cloud admin sent and accepted the invitations and ran the enrollment. I planned the sequence, prepared the landing OU, sign-on and baseline policies, and verified each account afterwards.
Why leave-then-join gets refused#
The classic way to move an account is leave, then join: the account leaves its organization as a member, runs standalone for a while, then accepts an invite from the new one. To leave, it must be able to stand alone, and that is where it gets stuck.
In accounts created inside an organization, the payment method is usually missing. That was true here, but adding a card wasn't enough: Leave still refused, and AWS's message doesn't say what else it wants. No public API reads whether a payment instrument exists (billing, invoicing, billingconductor, account, ce and budgets all come up empty), but the console does: Billing, then Payment preferences, in the member account lists payment methods. The Leave dialog itself only said:
You can't leave the organization yet
AWS documents a "Complete the account sign-up steps" link for this message. With the invite path, you can skip it. If your migration plan depends on someone typing a payment card into every account by hand, send it back; there's a better path.
A refused removal is safe, but it is not a dry run
The 400 changes nothing. But if the prerequisites are met, that same call removes a production account from its organization on the spot. Do not use it to "test" readiness.
Invite from the destination instead#
On 19 November 2025 AWS announced direct account transfers. The destination management account invites the account, the account accepts, and it moves straight across without leaving its old organization first or running standalone in between. In practice the invitation went through, and on acceptance the account left its old organization automatically, with no separate leave step.
The API reference makes this easy to miss. The InviteAccountToOrganization reference still lists ALREADY_IN_AN_ORGANIZATION as a failure reason, though read closely, that list sits under a caveat:
Some of the reasons in the following list might not be applicable to this specific API or operation.
The account migration guide describes the direct transfer, and the API reference's error list is shared boilerplate. When the two disagree, I go with the user guide.
| Leave, then join | Invite from destination | |
|---|---|---|
| Standalone prerequisites | Required before leaving | AWS's docs say none needed |
| Payment card per account | Typed in by hand | Not mentioned in AWS's docs. Untested here: the one invited account already had a card. |
| Billing gap | A standalone period outside consolidated billing | None |
| Who acts | Member account leaves, then accepts an invite | Destination invites, member accepts |
| Outcome here | Refused, even with a card added | Worked |
The two ways to move an account, as they played out here.
The commands themselves are short. Invite from the destination's management account, then accept in the member account:
aws organizations invite-account-to-organization \
--target Id=123456789012,Type=ACCOUNT
aws organizations accept-handshake --handshake-id h-examplehandshakeid111
Read the guide's prerequisites first: rules on the age of the account and the organization, a Seller of Record that must match, and the fact that the account lands in the root of the new organization. Per the invitations page, invitations expire after 15 days and the new organization's policies apply as soon as the account joins. If your team plans to leave, then join, ask them why; the invite path skips per-account billing setup and the standalone gap.
How to move an AWS account to another organization, step by step#
With AWS Control Tower in the destination, "moved" really means "moved and enrolled in the right organizational unit (OU)". The sequence:
- Register the landing OU with Control Tower while it is still empty. For an empty OU it took about two minutes here; AWS's guidance is to plan for ten or more. Control Tower attaches its own
aws-guardrails-*SCP (a service control policy: an org-level policy that can only deny, never grant). That is expected, not drift. - Associate security monitoring with the OU before anything arrives.
- Invite from the destination; accept in the member account.
- Create the
AWSControlTowerExecutionrole in the account. - Enroll the account through Control Tower into the OU. Until enrollment, the account sits in the root under whatever policies are attached there, so enroll it the same day.
The full move, from invitation to the cleanup that makes the account fully yours.
The execution role trusts the destination's management account. This is the shape from the enrollment prerequisites; replace 111122223333 with your destination management account ID:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::111122223333:root"
},
"Action": "sts:AssumeRole"
}
]
}
The role also needs the AdministratorAccess managed policy, or enrollment fails:
aws iam create-role --role-name AWSControlTowerExecution \
--assume-role-policy-document file://trust.json
aws iam attach-role-policy --role-name AWSControlTowerExecution \
--policy-arn arn:aws:iam::aws:policy/AdministratorAccess
I don't use aws organizations move-account for step 5. With auto-enrollment off, a manual move into a Control Tower OU does not enroll the account and causes inheritance drift. If you want moves to enroll on their own, Control Tower offers automatic enrollment on landing zone 3.1 and later.
I also wouldn't move every account at once. Order them by access risk, and hold back any account whose permission sets don't yet exist in the destination. Whoever owns the migration should confirm the landing OU and its security monitoring are in place, and checked, before the first account arrives.
Sign-on after the move#
For users, the account disappeared from the old access portal and appeared in the new one with the same groups, with no access requests to re-file. This works only because the destination's directory already had the same groups, and permission sets were assigned to them on arrival. Nothing in Identity Center carries over by itself. The destination's IAM Identity Center creates the new sign-on roles (AWSReservedSSO_*) when permission sets are assigned, as Identity Center does.
If a group doesn't exist in the destination's directory, its members lose that path into the account, so create groups and permission sets in the destination before you move anything. Engineers will also hit a confusing error: a CLI profile still pointing at the old portal fails with ForbiddenException ... No access. It reads like a missing permission, but it's just the old portal. Point the profile at the new start URL and sign in again.
Root email addresses come across unchanged. One of ours pointed at a mailbox on a legacy domain, so check each one. Budget an identity prep step before the move, and tell engineers ahead of time that their CLI profiles will need a new start URL.
Enrolled is not the same as governed#
Run a parity check against the organization's own guardrails after each move. On these moves, the accounts were enrolled, recording AWS Config and reporting to the security services, yet outside every one of the organization's own baseline policies, the SCPs and configuration policies (an EC2 declarative policy and an S3 policy, which set a service's configuration directly), for most of a week.
A dashboard showing "enrolled" means Control Tower's own controls apply, nothing more. Your organization's policies apply to an OU only if they are attached to it or inherited from above it. Here the baseline was attached OU by OU, not at the root, so a brand-new OU inherited none of it. Attaching policies that are safe everywhere at the root closes this class of gap; the trade-off is a wider blast radius for every change to them.
There is no effective-policy API for SCPs, so the check walks the parent chain. Configuration policies do have one:
#!/usr/bin/env bash
# Run with management account credentials.
# List the SCPs that reach an account: its own, each parent OU's, and the root's.
set -euo pipefail
target="${ACCOUNT_ID:?set ACCOUNT_ID}"
while true; do
echo "== ${target}"
aws organizations list-policies-for-target \
--target-id "${target}" --filter SERVICE_CONTROL_POLICY \
--query 'Policies[].Name' --output text
read -r parent_id parent_type < <(aws organizations list-parents \
--child-id "${target}" --query 'Parents[0].[Id,Type]' --output text)
target="${parent_id}"
if [[ "${parent_type}" == "ROOT" ]]; then
echo "== ${target} (root)"
aws organizations list-policies-for-target \
--target-id "${target}" --filter SERVICE_CONTROL_POLICY \
--query 'Policies[].Name' --output text
break
fi
done
# Configuration policies have an effective-policy API.
# Repeat with --policy-type DECLARATIVE_POLICY_EC2.
aws organizations describe-effective-policy \
--policy-type S3_POLICY --target-id "${ACCOUNT_ID}"
Two details keep a check like this honest. Control Tower's list-enabled-baselines returns an OU as an ARN, while Organizations uses the bare ou- ID, so compare like with like. And list the policy types your organization has enabled (aws organizations list-roots --query 'Roots[0].PolicyTypes') instead of hard-coding them, or a check can silently skip one.
Attach missing policies one at a time, smallest blast radius first, and take care with one type in particular:
An S3 policy changes live state on attach
An SCP only denies future calls. An Organizations S3 policy overrides the account's Block Public Access settings the moment you attach it. A bucket that is public today stops being public. Detaching it restores the previous settings. If one account in the OU has public content that must stay public until its owner decides, attach the S3 policy to the other accounts individually and move it to the OU later.
The same check found a long-governed account missing baseline policies too, so the gap is not unique to new OUs. Make the parity check a runbook step after every move, and don't accept a dashboard's "enrolled" as proof that your own policies apply.
The old organization's admin role#
Accounts created inside an organization get OrganizationAccountAccessRole, an admin role the management account can assume. Invited accounts do not get one in the new organization.
The old one is the problem. It survives the move, still trusts the old organization's management account, and still has admin rights, so whoever controls that old management account can still administer the account you just moved. The cleanup comes after the move because, until AWSControlTowerExecution and Identity Center access exist, the old role is the only admin path. Do it the same day.
aws iam get-role --role-name OrganizationAccountAccessRole \
--query 'Role.AssumeRolePolicyDocument'
It isn't the only role to check. Old-org StackSets execution roles can also trust the old management account:
aws iam list-roles \
--query "Roles[?contains(to_string(AssumeRolePolicyDocument), '${OLD_MGMT_ACCOUNT_ID}')].RoleName"
Replace your access path before you remove the old one
Verify both paths first: the human path (you can sign in through the new organization's Identity Center) and the automation path (AWSControlTowerExecution is assumable from the new management account). Then delete the old role, or retrust it to the new management account.
An account is not migrated until the old organization can no longer administer it. Make that an explicit exit criterion for every move, with someone named to verify it.
Running the next move#
Treat each account as its own change: one ticket, both checklists, and a named person for the exit check. Put the baseline attach and the old-role cleanup inside the enrollment runbook, so they happen on move day rather than in a follow-up. If the payment question matters for your budget, invite one account that has no card on file before you plan the rest around either answer.
Before the move:
- Read the account migration prerequisites: account and organization age, matching Seller of Record
- No SCP or IAM policy in the source organization blocks the migration
- Resource policies using
aws:PrincipalOrgIDfound and updated (they break silently after the move) - Account deregistered as a delegated administrator, if it is one
- Organization-level billing history exported (AWS deletes it on removal)
- No existing AWS Config recorder or delivery channel left in the account (remove before enrolling)
- Groups and permission sets exist in the destination's Identity Center
- Landing OU registered with Control Tower while empty
- Security monitoring associated with the landing OU
- Accounts ordered by access risk; any account missing identity prep held back
- Root email addresses reviewed
After the move:
- Invitation accepted within its 15-day window
-
AWSControlTowerExecutioncreated withAdministratorAccessand the account enrolled into the OU (notmove-account) - Users can sign in through the new portal; CLI profiles updated
- Parity check: the organization's baseline SCPs and configuration policies reach the account
- Sanctioned public content checked before any S3 policy is attached
- Old
OrganizationAccountAccessRole, and any other role trusting the old management account, deleted or retrusted
Paste both lists into the ticket for each account, and don't close it until every box is ticked. If you're planning a move like this and want a second pair of eyes on the order of operations, book an intro call. The full engagement it came from is in the AWS governance case study.
Frequently asked questions
Can I move an AWS account to another organization without leaving the old one first?
Yes. AWS documented direct account transfers in November 2025. The destination organization's management account sends an invitation, the member account accepts, and it leaves the old organization automatically. AWS's guide says it does not need to operate as a standalone account first.
Does a moved account need a payment method?
For the leave-then-join path, the account must meet the standalone prerequisites, and in accounts created inside an organization the payment method is usually missing. Adding a card was not enough in our case: Leave still refused. For the invite path, AWS's guide does not mention a payment method, but I have not tested an account with no card on file.
Does an invited account get OrganizationAccountAccessRole?
No. Only accounts created inside an organization get that role. An invited account keeps whatever roles it had, including the old organization's OrganizationAccountAccessRole, which still trusts the old management account. Replace your access path, then delete or retrust that role as part of the move.
Should I use aws organizations move-account to put the account in the right OU?
Not in a Control Tower landing zone with auto-enrollment off. A manual move puts the account under the OU without enrolling it and causes inheritance drift. Create the AWSControlTowerExecution role in the account and enroll it through Control Tower into the target OU instead.
Shahid Yousuf
Senior Software Engineer
I build and consult on software across web, mobile, cloud and AI. Have something in mind? Let's talk.
Hire me Book a free intro call See case studies