Once upon a time, my friend and mentor David Reed gave a talk on error handling that totally blew my mind. Imagine if you had a system in your life that could tell you what went wrong and what to do about it, before the mistake causes you problems:

  • *oops! you’re leaving the house without your credit card again. go back to your hoodie pocket where you put it for convenience and put it where it belongs*
  • *you are on your last pair of underwear. begin laundry cycle today or you will be screwed*
  • *you just followed the instructions for knitting row 15, but you are on knitting row 16. i suggest you go back and redo*
  • *stop before you put salt in your coffee!*

Now, imagine a vague and unhelpful “life error message.” Sort of like that gnawing feeling of, “you are forgetting something, but I can’t tell you what!” That’s how I experience this error.

Making error messages thoughtful and helpful requires an uncommon amount of empathy and advance planning and resources. That’s probably why we see so many generic ones like #Value in Excel or “404 bad gateway” online or “blue screen of death.”

In this blog post, I’m going to get up close and personal with a particularly vexing error message in Salesforce. I hope this blog post will help a fellow traveler in their troubleshooting journey OR help a learner begin to think about HOW to troubleshoot (even if you aren’t facing this issue). So, I invite you to wade through the technical mumbo jumbo with me with an open mind, whether or not this directly applies to your current situation.


I have encountered this error twice in the past few weeks, and it seems that I’m not the only person on the internet who finds this vexing.

As the reddit commenter above says,

“Insufficient access rights on cross-reference id? Could mean a permissions issue, could mean the record is deleted, could mean the id was wrong. Big pain.”

In other words, a wild goose chase.

Scenario 1: Sending an email from a Flow

My dear friend built a Record-triggered (after save) Flow that sends an email when a picklist is set to a certain value on a custom object. It’s a really neat solution that you might have seen if you attended the November edition of Demo Org Demo Jam! However, she hit this perplexing error and was quickly discouraged.

All of the “easy” or “obvious” troubleshooting options came up dry. In particular, we checked all of the field and object permissions. Email deliverability was on and the profile had email permissions. The org did not have Roles or record access restrictions. What could be causing the issue?

I learned through some research (for anyone who comes across this blogpost with the same issues) that you should definitely check the sharing permissions on the Email Template and/or Email Template Folder.

However, our particular issue was closer to this Stack Exchange poster – we had mapped the wrong field to the Recipient Id in the Send Email standard flow action. Since this is a standard action, it seems hypothetically possible to validate this(these?) input(s) and provide a more useful error message. While I now understand that the “cross reference” is referring to the Contact lookup or the Email template, it was not immediately obvious to me – at all.

Scenario 2: Partner Community User creates an Account record

This week, my coworker and I were troubleshooting a Screen Flow where the running user (in this case, a Partner Community User authenticated in an Experience Cloud Site) needs to create a new Account record if they cannot find an existing Account in a lookup field. Seems normal, right? We have Partner Community Users make records All. The. Time. That’s, like, the whole point of having forms hosted in an Experience Cloud Site. So why were we getting this tricky error?

While I was debugging, I reduced the complexity of the Flow to include ONLY two fields – Account Name (standard field) and EIN (custom field). I know the user has access to these fields because they had to populate them in order to get a Partner User account in the first place. I also checked Role hierarchy and Org Wide Defaults to make sure that the Portal User could theoretically access these records. So what gives?

Ultimately, my issue was most closely related to this Stack Exchange poster. Since my issue didn’t map on exactly, I couldn’t follow the instructions laid out precisely. However, I do want to share the troubleshooting experiment that DID lead me to the correct conclusion. I tried using a different test user (with the same license and profile type) and quickly came to the conclusion that I got the error with one user, but not the other (!!!!). Even though they were functionally the same in every way (I checked, oh reader, I checked). The only difference I could eke out was a different Record Owner. (FORESHADOWING!!) But who cares? I kinda feel like record owner should have no bearing on permissions when Accounts are public read/write. This was the “smoking gun” I suppose!

I modified the Flow to make the “owner” of the new record created the same as the “owner” of the User’s Contact’s Account record. (If you’re a little lost on the details here, don’t worry. It has to do with how Experience Site users get set up in Salesforce, but it’s not the main takeaway). And once I had this up and running, no more errors presented.

I can’t find any locations in Salesforce documentation that explains the prohibition where Partner Community users cannot create Account records unless the Account Owner matches their, um, grandparent record’s owner? Security and access is not my biggest platform strength but I’ve studied the concepts enough to pass my exams and I read pretty much everything that exists on the internet that hit my keyword searches related to this issue. And I still don’t entirely understand the foundational concept that makes this mismatching Record Owner thing present this particular error. If a reader knows and can put me out of my misery, I would be eternally grateful. Scroll don’t skim (run don’t walk??) to the comments and tell me asap!

If you are having this problem and you need an immediate solution, an easier way out is to set the Flow to run in System Context. We did this in my org, but I wasn’t satisfied because I wanted to find a root cause solution!

Scenario 3: Lookup field is blank / record does not exist

This one is absolutely maddening! I have an org where we have an extensive “tree” of Campaigns; Campaigns in this org represent events. We have automation that automatically sets some values when Campaigns are created or updated. In some cases, including our flagship application campaign, decision elements or assignment elements in the Flow contain hard-coded record Ids.

Every once in awhile, we combine Campaigns (for example, if one is under-enrolled or no longer necessary). It’s useful and important to have a clean campaign hierarchy for visual clarity and for reporting!

In one case, I had deleted a Campaign that was referenced in a Flow and we somehow hit the criteria that brought us to that area of the automation. It was awhile ago so I am fuzzy on the details! However, we hit the *ding ding ding* “insufficient access rights on cross-reference id” error. I was absolutely perplexed on this one! It turns out that if the record does not exist, the security model in Salesforce interprets the scenario the same way as if the record DOES exist, but the running user cannot access it. This is particularly ouchy in a Sandbox!

Scenario 4: using an outdated API version in code

I really enjoyed this blog post about interpreting our quixotic error message. The writer determined that the Object which the code queried was not included in the API version referenced in the code! YIKES! That must have been next level sleuthing. I’ve linked to the blog post in the button below.

Scenario zillion: What else can be causing this error?

The list is rather shockingly long. Here’s a quote I found on an IT training provider’s website:

The error “insufficient access rights on cross reference id.” is thrown when you try to insert/update something that logically cannot be inserted/updated. Some examples:  You try to update a record that does not exist. Maybe the record was never there or it was deleted. You try to update an object field that cannot be set explicitly. These fields can only be updated by the implicitly. e.g.: object owner, CreatedById, CreatedDate, LastActivityDate, LastModifiedById, LastModifiedDate. You cannot explicitly update these fields. You are trying to give permission to someone but you yourself do not have permission for this. If you are trying to share “Record X” with “User Y” and you yourself do not have access to “Record x”, this error happens Or if the “User Y” already has access to it. These are just a few reasons you can get the salesforce error INSUFFICIENT_ACCESS_ON_CROSS_REFERENCE_ENTITY; I am sure there are others.

This error message is so notorious and difficult to troubleshoot that Salesforce even has documentation on scenarios that can cause the error to appear.

They all seem very specific to scenarios with certain objects and metadata. Therefore, why can’t Salesforce develop more detailed error messages that respond to each of these? Having a vague error message is like sending me to find a needle in a haystack!


As always, I love to hear from you. If you have encountered one of these scenarios, or if you are stuck on this error yourself, please leave me a comment. Additionally, if you have more info on what I’ve discussed here that can help me learn, I’d love to benefit from your wisdom. And if you have the power to change how this error message is used on the Salesforce platform, please please please reach out!

7 thoughts on “demystifying the INSUFFICIENT ACCESS ON CROSS REFERENCE ENTITY error in salesforce

  1. Great post, Sam! I don’t have to create these error messages, but I sure get them all the time, especially that 404 one!
    Keep up this amazing work!

  2. Thank you for documenting this. I’m sure it will help a lot of people. A funny and enjoyable read, too!

  3. In with sharing apex, when creating or updating a record with lookup fields set or updated to reference a record for which the contextual user has no sharing access, this same unhelpful error is thrown.

  4. The timing of this post is incredible! I was struggling with this error the other day – a Flow was attempting to delete an undelete-able sharing record created via a sharing rule. It took way too long to figure out because of the vagueness of the error message!

    And I love that statement about error message planning and writing requiring a ton of empathy. I totally want to bring this way of thinking – putting myself into the end user’s shoes – into my dev work in the next year and beyond.

  5. It can be tough to lean into the mindset of “I love error messages” when you so rightly point out that they aren’t always structured in a way that can be ultimately helpful. But it is oh. so. satisfying when you finally find out what makes that error disappear. Thanks for sharing your experience on this one!

  6. Would be helpful to link (or create) an idea on the Idea Exchange. I know that it counts for *almost* nothing, but without that as a reference point it makes it harder to poke under people’s noses at Salesforce and gives them plausible deniability #TickTheBox. When creating the idea, you can always link back to this post 🙂 Wishing you success!

    p.s. Sometimes a star does come along and actually even uses the feedback on the Idea Exchange (e.g. the wonderful Cheryl Feldman)

Leave a Reply