Summary:

A corrupt synch state on CRM folder items can cause synchronisation to fail.

Symptoms:

An error will be logged in the Exchange synch engine's exchangesynch.log:


Main exception string: Synchronization state data is corrupt or otherwise invalid
Exception code: ErrorInvalidSyncStateData
Impersonated user: mayes@panoply-tech.com
com.sage.scrm.syncengine.exchange.ews.service.error.SageDetailedExchangeServiceException: Parsed Exchange Exception
Main exception string: Synchronization state data is corrupt or otherwise invalid.
Exception code: ErrorInvalidSyncStateData
Impersonated user: exchange-user@panoply-tech.com
at com.sage.scrm.syncengine.exchange.ews.service.SageExchangeService.syncFolderItems(SageExchangeService.java:516)
at com.sage.scrm.syncengine.exchange.ews.service.SageExchangeService.syncFolderItems(SageExchangeService.java:438)
at com.sage.scrm.syncengine.exchange.ews.sdata.sync.SyncSourceManagerBase.syncFolderItemsForUser(SyncSourceManagerBase.java:490)
at com.sage.scrm.syncengine.exchange.ews.sdata.sync.SyncSourceManagerBase.updateSynchronizationEntries(SyncSourceManagerBase.java:425)
at com.sage.scrm.syncengine.exchange.ews.sdata.sync.SyncSourceManagerBase.updateSynchronizationEntries(SyncSourceManagerBase.java:382)
at com.sage.scrm.syncengine.exchange.ews.endpoint.EWSEndpoint.getFirstSyncSourcePage(EWSEndpoint.java:80)
at com.sage.scrm.syncengine.exchange.engine.SynchronisationProcess.execute(SynchronisationProcess.java:139)
at com.sage.scrm.syncengine.exchange.engine.SynchronisationThread.synchroniseResourceOneWay(SynchronisationThread.java:296)
at com.sage.scrm.syncengine.exchange.engine.SynchronisationThread.synchroniseResourcesOneWay(SynchronisationThread.java:277)
at com.sage.scrm.syncengine.exchange.engine.SynchronisationThread.run(SynchronisationThread.java:173)
at java.lang.Thread.run(Unknown Source)
ESTABLISHING_CONNECTION_EWS_ENDPOINT

In this case, the root error is being returned by the Exchange Web Services endpoint. The error appears as a response to a call to the syncFolderItems method:

http://msdn.microsoft.com/en-us/library/exchangewebservices.exchangeservicebinding.syncfolderitems(v=exchg.140).aspx


Cause:

When an item is synchronised with Exchange, a state string is sent by CRM to Exchange as part of the SyncFolderItems method. This is a Base64-encoded string that describes the status of a record at a given time.

The way that this works is that Exchange does not keep a record of the last synch state on the CRM side - this is returned to CRM as part of the synch. On the next synch, the CRM synch engine will send the synch state to Exchange, which will then be used to determine if updates should be sent to CRM.

A valid request would look something like the below, from an example cxf-general.log:

Address: https://ExchangeServer/ews/exchange.asmx
Encoding: UTF-8
Content-Type: text/xml
Headers: {SOAPAction=["http://schemas.microsoft.com/exchange/services/2006/messages/SyncFolderItems"], Authorization=[Basic c29tZXVzZXJAdGVzdC5jb206WW91cmVWZXJ5Tm9zeQ==], Accept=[*/*]}
Payload:
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Header>
<ExchangeImpersonation xmlns:ns2="http://schemas.microsoft.com/exchange/services/2006/messages" xmlns="http://schemas.microsoft.com/exchange/services/2006/types">
<ConnectingSID>
<PrimarySmtpAddress>mayes@panoply-tech.com</PrimarySmtpAddress>
</ConnectingSID>
</ExchangeImpersonation>
<RequestServerVersion xmlns:ns2="http://schemas.microsoft.com/exchange/services/2006/messages" xmlns="http://schemas.microsoft.com/exchange/services/2006/types" Version="Exchange2007_SP1">
</RequestServerVersion>
</soap:Header>
<soap:Body>
<ns2:SyncFolderItems xmlns="http://schemas.microsoft.com/exchange/services/2006/types" xmlns:ns2="http://schemas.microsoft.com/exchange/services/2006/messages">
<ns2:ItemShape>
<BaseShape>IdOnly</BaseShape>
<AdditionalProperties>
<FieldURI FieldURI="item:DateTimeCreated"/>
<FieldURI FieldURI="item:LastModifiedTime"/>
<ExtendedFieldURI PropertyType="String" PropertyTag="0x3a45"/>
<ExtendedFieldURI PropertyType="String" PropertyName="CRMCONTACTID" PropertySetId="62077ce4-4037-4738-9ebf-5f0ba7ce160a"/>
</AdditionalProperties>
</ns2:ItemShape>
<ns2:SyncFolderId>
<DistinguishedFolderId Id="contacts"/>
</ns2:SyncFolderId>
<ns2:SyncState>
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
</ns2:SyncState>
<ns2:MaxChangesReturned>100</ns2:MaxChangesReturned>
</ns2:SyncFolderItems>
</soap:Body>
</soap:Envelope>

This SyncState data may become corrupt or truncated – most likely, a bad state was sent by Exchange to CRM on a previous run of the synchronisation. You can view the user's synch states by running the following:

select * from EWSFolder
where EWFO_MailboxID = (
select User_UserId from Users
where User_EmailAddress = N'mayes@panoply-tech.com')



Resolution:

This issue can be resolved by NULLing the state information for a given folder on the CRM side. This will cause EWS to generate new state information, and resynch the folder. This can be done on an entity-by-entity basis (if the problem entity is known), or can be done for all entities (contacts, appointments and tasks) for a given mailbox.

As an example, to clear the contact state information for a mailbox named mayes@panoply-tech.com, run the following SQL:

update EWSFolder
set EWFO_SyncState = NULL
where EWFO_EntityID = (
    select ESEN_EntityID from EWSEntity 
    where ESEN_Name = N'contact')
and EWFO_MailboxID = (
    select EWMA_MailboxID from EWSMailbox
    where EWMA_Email = N'mayes@penaoply-tech.com')

Synch state data can be cleared for all entities by removing the highlighted line above.

If a remaining item hasn't been synched across, it can be re-synched by setting exsr_DoesResourceExistInTarget to 0 for any affected resources.