LowCodeStacks
Sign in

Dataverse access cheat sheet: privileges, access levels and 'missing privilege' errors

How Dataverse decides whether someone can see or change a row, what each privilege and access level really grants, and the fix for every common access error, from 'missing privilege' to 'can't open the environment'.

DataverseLook it up · Quick reference6 min read

Checked against Microsoft Learn · 8 sourcesHow we write guides

"It works for me but not for them" is the most common Dataverse support request. Dataverse runs two checks every time someone touches a row, and almost every access error means one of them failed. Once you know which one, the fix is quick.

The two checks

1. The privilege check: are they allowed to do this to this kind of row at all?

The user needs the privilege, for example Write on the Contact table, through a security role assigned to them directly, or to a team they're in. The access level doesn't matter yet; this check only asks "is the privilege there?" If it fails, they get a missing privilege error.

2. The access check: may they do it to this particular row?

Only once the privilege check passes does Dataverse look at the row itself. Access can come from any one of four routes:

RouteThey get access because…
OwnershipThey own the row, or a team they belong to owns it
Role accessTheir role's access level reaches the row's business unit (table below)
Shared accessSomeone shared the row, or a related row, with them, their team or the whole organization
Hierarchy accessHierarchy security is on for that table, and they manage the owner (needs Business Unit or Parent:Child access)

If the privilege check passes and all four routes fail, the error says they don't have the access right for that row, not that a privilege is missing. That difference tells you where to look.

The eight privileges

PrivilegeLets them…
CreateAdd a new row
ReadOpen and view a row
WriteChange a row
DeletePermanently remove a row
AppendAttach this row to another row (for example attach a note to an opportunity: Append on Note)
Append ToHave other rows attached to this row (for example add a note to an opportunity: Append To on Opportunity)
AssignGive the row to a different owner
ShareGive someone else access to the row while keeping their own

Tip

Setting a lookup is "attaching". To fill Account on a Contact, the user needs Append on Contact and Append To on Account. For many-to-many relationships, they need Append on both tables. Missing one half is the classic cause of "I can edit the row but can't set that lookup".

The access levels

Each privilege in a role has an access level. It decides which rows the privilege applies to.

LevelApplies to rows…Typical for
Nonenone
Userthey own, that their teams own, or that are shared with them or their teamsMost users
Business Unitowned by anyone in their business unitTeam leads
Parent: Child Business Unitsin their business unit and every unit below itManagers of a division
Organizationin the whole environmentAdmins, people working across all data

Each level includes everything above it in this table. Tables owned by the organization (rather than by users or teams) only have None or Organization, and so do the miscellaneous and privacy privileges, such as "Export to Excel".

Warning

Granting Organization-level Read "just to make it work" exposes every row in the table to everyone with that role. Fix the actual gap instead.

Teams, in one minute

  • Owner teams can own rows and have security roles. Members get the team's privileges plus their own.
  • Access teams have no roles and own nothing. Rows are shared with them with specific rights (Read, Write, Append and so on).
  • Team roles and a member's own rows depend on the role's Member's privilege inheritance setting. Set to Team privileges only, a role with User-level access applies only to rows the team owns, so members can't use it on their own rows. If members must create and edit rows they own, give them a role directly, or check that setting.

Errors and what to do

What they seeWhich check failedFix
"One or more commands are unavailable due to your current privileges for this environment"PrivilegeAdd a role with the missing privilege. For solution work, they usually need Environment Maker or System Customizer
"Principal user (Id=…) is missing prvReadAccount privilege" (code -2147220960)PrivilegeThe name says it all: prv + action + table. Add Read on Account to one of their roles
"CrmCheckPrivilege failed … on UserId … and Privilege …" (code -2147220839)PrivilegeSame fix: find the named privilege and grant it
"Principal with id … does not have CreateAccess right(s) for record … " (code -2147187962)AccessThe privilege exists but doesn't reach this row. Raise the access level, change the owner, or share the row
Can't set a lookup, or the related row doesn't appear in the lookupPrivilege (Append or Append To)Grant Append on the row being edited and Append To on the related table
The user can't open the environment or app at allBefore both checksThey need a role in the environment, a valid licence, and membership of the environment's security group if it has one
A newly licensed or newly added user still can't get inBefore both checksLicence and group changes take time to sync. An admin can re-add the user to the environment to force the sync
A flow or integration fails with a "missing privilege" errorPrivilege, for the connection's identityThe account or application user the connection runs as needs the role, not the person who built the flow

How to find out what someone can see

  • Check Access. On any row in a model-driven app, select Check Access. It shows your own rights on that row and which route gives them. Admins can look up another user, and with two environment settings turned on, see who has access to the row and why: direct role, team role, shared or application user.
  • Test as them. Make a test user with exactly the target roles and sign in as them. Admin accounts pass every check, so testing as yourself proves nothing.

Start from the right role

  • App Opener: the minimum needed to run an app. Use it as the base for a custom role.
  • Basic User: the minimum plus the core business tables.
  • Copy a template, don't start from scratch. Use Copy table permissions to give several custom tables the same settings at once, but remember it overwrites the target tables' settings.

Sources