Skip to page contentSkip to chat
ServiceNow support
    • Community
      Ask questions, give advice, and connect with fellow ServiceNow professionals.
      Developer
      Build, test, and deploy applications
      Documentation
      Find detailed information about ServiceNow products, apps, features, and releases.
      Impact
      Accelerate ROI and amplify your expertise.
      Learning
      Build skills with instructor-led and online training.
      Partner
      Grow your business with promotions, news, and marketing tools
      ServiceNow
      Learn about ServiceNow products & solutions.
      Store
      Download certified apps and integrations that complement ServiceNow.
      Support
      Manage your instances, access self-help, and get technical support.
Duplicate entry for key 'PRIMARY' on Insert of a CMDB CI when the Computer/Server being inserted is Virtual - Support and Troubleshooting
  • >
  • Knowledge Base
  • >
  • Support and Troubleshooting (Knowledge Base)
  • >
  • Duplicate entry for key 'PRIMARY' on Insert of a CMDB CI when the Computer/Server being inserted is Virtual
KB0748828

Duplicate entry for key 'PRIMARY' on Insert of a CMDB CI when the Computer/Server being inserted is Virtual


5543 Views Last updated : Jul 24, 2025 public Copy Permalink
KB Summary by Now Assist

Issue

While inserting a Computer/Server CI in the CMDB, either manually, via a Discovery tool, or some other import, you may see errors at the SQL level related to failure to insert the CI because it is already inserted. Other code running as part of the insert, or in reaction to the insert, may not work as expected.

e.g. 

FAILED TRYING TO EXECUTE ON CONNECTION nn: INSERT INTO cmdb (`a_str_5`, `a_int_8`, `skip_sync`, `operational_status....
java.sql.BatchUpdateException: Duplicate entry '7caaf9c31b9dff846825a64fad4bcb6a' for key 'PRIMARY' 
: java.sql.SQLException: java.sql.BatchUpdateException: Duplicate entry '7caaf9c31b9dff846825a64fad4bcb6a' for key 'PRIMARY': com.glide.db.StatementBatcher.getSQLException(StatementBatcher.java:469)

Release

Any instance with Discovery or Service Mapping installed.

Cause

There is probably a custom business rule running for insert of CI relationships, that makes an update to the parent CI before it exists. This causes a premature insert, after which anything else running as part of the transaction will probably behave in various spectacularly unexpected ways. Let me explain:

  • If the CI being inserted is a Computer [cmdb_ci_computer], or Server or some other class that extends Computer, then the out-of-box business rule "Virtual Computer Check" will run.
  • This runs before insert of the Computer CI, because the "IsVirtual" flag needs adding before insert.
  • If this finds a VM instance record, it known the CI is Virtual, and also create an "instantiates" relationship between VM and Instance. A Relationship record is inserted.
  • All insert Business Rules for a Relationship record [cmdb_rel_ci] will run as the Relationship record is inserted.
  • If the custom business rule makes an .update() to the parent of the relationship, causing a premature insert because the computer CI hasn't inserted yet.
  • The remaining Relationship insert business rules complete.
  • The remaining before insert Computer CI business rules complete.
  • Now the actual Computer CI insert should happen, but it errors because the sys_id was inserted already.

Resolution

You cannot assume that both parent and child CIs exist at the point that the Relationship record is inserted. "Virtual Computer Check" is just one example of code that may insert the relationship before the CI, and there are probably others.

You need to avoid causing a premature insert, as other out-of-box code cannot cope in this situation.

Your custom implementation needs redesigning so that it takes these facts into account.

Related Links

It has always been the platform behavior that a get for a nonexistent record will initialize a new GlideRecord. The same applies when dot walking reference fields in scripts to get the object of the referenced record, as in this case. Any subsequent update to that will cause an insert.

That insert behavior is documented in the GlideRecord documentation (Server API), under update(): "Updates the GlideRecord with any changes that have been made. If the record does not exist, it is inserted."


The world works with ServiceNow.

Sign in for more! There's more content available only to authenticated users Sign in for more!
Did this KB article help you?
Did this KB article help you?

How would you rate your Now Support digital experience?

*

Very unsatisfied

Unsatisfied

Neutral

Satisfied

Very satisfied

Very unsatisfied

Unsatisfied

Neutral

Satisfied

Very satisfied

What can we improve? Please select all that apply.

What are we doing well? Please select all that apply.

Tell us more

*

Do you expect a response from this feedback?

  • Terms and conditions
  • Privacy statement
  • GDPR
  • Cookie policy
  • © 2025 ServiceNow. All rights reserved.