-
-
Notifications
You must be signed in to change notification settings - Fork 250
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
ErrorInvalidSchemaVersionForMailboxVersion with exchangelib v5.2.1 and Exchange server version 15.2.1544.4 #1301
Comments
Thanks for the report! We made the change in API version from Does switching back to exchangelib v4.9.0 actually work? If so, you can test this workaround in v5.2.1: import exchangelib.version
tmp = list(exchangelib.version.VERSIONS)
tmp[1] = (exchangelib.version.EXCHANGE_2019, "Exchange2019", "Microsoft Exchange Server 2019")
exchangelib.version.VERSIONS = tuple(tmp) |
Thanks for your quick response! I noticed that for the failing request, the response headers do not include the fields |
In that case, your best bet is to run a successful and a non-successful connection attempt and compare the XML requests and responses. You can also try hardcoding the version number in the connection: from exchangelib.version import EXCHANGE_2019, Version
account = Account(
...
config=Configuration(
version = Version(build=EXCHANGE_2019),
...
),
) to see if that will get you past the error. |
I am getting the same error with both exchangelib 5.2.1 and 5.3.0, and it still occurs if I use a Configuration object with the Exchange version hardcoded. Downgrading to exchangelib 5.2.0 makes the error go away. |
To find out what's wrong you'll need to compare the XML requests and responses of a working and non-working version. Enable debug logging and post the request and response where the two versions differ. |
Hardcoding the version did not solve the problem on the v5.2.1 for us either. I looked into the requests and responses for both v4.9.0 and v5.2.1.
<t:DistinguishedFolderId>root</t:DistinguishedFolderId>
<t:PermissionSet>
<t:Permissions>
<t:Permission>
<t:UserId>
<t:DistinguishedUser>Default</t:DistinguishedUser>
</t:UserId>
<t:CanCreateItems>false</t:CanCreateItems>
<t:CanCreateSubFolders>false</t:CanCreateSubFolders>
<t:IsFolderOwner>false</t:IsFolderOwner>
<t:IsFolderVisible>false</t:IsFolderVisible>
<t:IsFolderContact>false</t:IsFolderContact>
<t:EditItems>None</t:EditItems>
<t:DeleteItems>None</t:DeleteItems>
<t:ReadItems>None</t:ReadItems>
<t:PermissionLevel>None</t:PermissionLevel>
</t:Permission>
<t:Permission>
<t:UserId>
<t:DistinguishedUser>Anonymous</t:DistinguishedUser>
</t:UserId>
<t:CanCreateItems>false</t:CanCreateItems>
<t:CanCreateSubFolders>false</t:CanCreateSubFolders>
<t:IsFolderOwner>false</t:IsFolderOwner>
<t:IsFolderVisible>false</t:IsFolderVisible>
<t:IsFolderContact>false</t:IsFolderContact>
<t:EditItems>None</t:EditItems>
<t:DeleteItems>None</t:DeleteItems>
<t:ReadItems>None</t:ReadItems>
<t:PermissionLevel>None</t:PermissionLevel>
</t:Permission>
</t:Permissions>
</t:PermissionSet> Note that on v4.9.0 api version "Exchange 2019" is tried first:
<t:FieldURI FieldURI="folder:DistinguishedFolderId"/> and then a block like this for each of the 22 more folders that are found compared to v4.9.0: <t:DistinguishedFolderId Id="allcategorizeditems">
<t:Mailbox>
<t:EmailAddress>some@mailaddress.com</t:EmailAddress>
<t:RoutingType>SMTP</t:RoutingType>
<t:MailboxType>Mailbox</t:MailboxType>
</t:Mailbox>
</t:DistinguishedFolderId> On v5.2.1 we get a faultcode response while on v4.9.0 the response holds the expected folder data. |
It looks like EWS doesn't like the GetFolder XML format of one or more of the child folders. Can you try out something like this? from exchangelib.folders import FolderCollection, SingleFolderQuerySet
for f in FolderCollection(account=account, folders=[account.msg_folder_root]).find_folders():
try:
f = SingleFolderQuerySet(account=account, folder=f).resolve()
print(f"GetFolder on folder {f.name} succeeded")
except Exception as e:
print(f"ERROR: GetFolder on folder {f} failed") |
Also, it would be great if you can post the full XML response containing the error message from the server when this happens. |
Worked great - we had a need to check each folder by id and the existing way of achieving this with account.root.walk() seems to be less reliable in recent versions due to the changes Microsoft are bringing in (denying access to Teams related folders etc). Code we've replaced:
|
It’s great that you can use it as a workaround, but I’d really like if you can post the folders printed in the error case. That may give a hint on how we can mitigate this issue. |
Of course - my apologies! We actually didn't get any errored folders which is an unexpected outcome considering the above, here are the logs:
|
Same's for our case, all the GetFolder calls for single folders succeed:
and also, here's the full debugging output for what i reported in a fragmented way earlier. This is what we get after |
Ok, then it must be a folder somewhere else. Can you try this (testing all folders under root)? from exchangelib.folders import FolderCollection, SingleFolderQuerySet
for f in FolderCollection(account=account, folders=[account.root]).find_folders():
try:
f_or_error = SingleFolderQuerySet(account=account, folder=f).resolve()
except Exception as e:
print(f"ERROR: GetFolder on folder {f} failed: {e}")
if isinstance(f_or_error, Exception):
print(f"ERROR: GetFolder on folder {f} returned error: {f_or_error}") |
Here you go (just to confirm I'm running 5.3.0):
The two that errored I can only assume are still the two TeamsMessagesData and TeamChatHistory folders 👍🏽 |
Super weird. None of that triggered an |
For the people reporting this, does the issue still appear in exchangelib 5.3.0? And can it be triggered with a simple |
for us the expected error came up for the last testing code block you posted @ecederstrand (still on v5.2.1): we have not tried v5.3.0 yet. will try do so asap. |
@ecederstrand Yes, the issue still appears in exchangelib 5.3.0. If I do
If I revert the version to 5.2.0, the issue is gone. |
Thanks for the stack trace! It reveals that it's an issue with distinguished folders, not child folders of the root folder. This snippet should reveal the culprit(s): from exchangelib.folders import SingleFolderQuerySet
from exchangelib.properties import DistinguishedFolderId, Mailbox
distinguished_folders = [
cls(
_distinguished_id=DistinguishedFolderId(
id=cls.DISTINGUISHED_FOLDER_ID,
mailbox=Mailbox(email_address=account.primary_smtp_address),
),
root=account.root,
)
for cls in account.root.WELLKNOWN_FOLDERS
if cls.get_folder_allowed and cls.supports_version(account.version)
]
for f in distinguished_folders:
try:
f_or_error = SingleFolderQuerySet(account=account, folder=f).resolve()
except Exception as e:
print(f"ERROR: GetFolder on folder {f.DISTINGUISHED_FOLDER_ID!r} failed: {e!r}")
continue
if isinstance(f_or_error, Exception):
print(f"ERROR: GetFolder on folder {f.DISTINGUISHED_FOLDER_ID!r} failed: {f_or_error!r}") |
I ran the script above using exchangelib 5.3.0 and an Exchange 2016 mailbox. This is the output I got:
|
Thanks for the output! That narrows down the problem considerably. It seems these distinguished folders are not supported on your Exchange version, which means we can just annotate these folders with Which exact version is your Exchange server? Please post the output of |
The referenced commit should fix the issue for you, @laurachan If others still have the issue even after be0cd9f then please run the code posted in #1301 (comment) and post the output in this thread. |
@ecederstrand I added the following to my
But when I run the debugging script #1301 (comment), I am still getting this error:
|
@quzhi1 What version of Exchange is that? |
@ecederstrand The version is
|
@quzhi1 I'm a bit sceptical whether you were actually running exchangelib at that commit, because when I run the test those folders are not in the list of distinguished folders when I hardcode the server version to 15.1.2507.39, even before I start talking to the server: account.version = Version(build=Build(15, 1, 2507, 39), api_version="Exchange2016")
distinguished_folders = [
cls(
_distinguished_id=DistinguishedFolderId(
id=cls.DISTINGUISHED_FOLDER_ID,
mailbox=Mailbox(email_address=account.primary_smtp_address),
),
root=account.root,
)
for cls in account.root.WELLKNOWN_FOLDERS
if cls.get_folder_allowed and cls.supports_version(account.version)
]
print(sorted([f.DISTINGUISHED_FOLDER_ID for f in distinguished_folders]))
# prints:
# ['allcontacts', 'allitems', 'allpersonmetadata', 'calendar', 'companycontacts', 'conflicts', 'contacts', 'conversationhistory', 'deleteditems', 'directory', 'drafts', 'favorites', 'fromfavoritesenders', 'imcontactlist', 'inbox', 'inference', 'journal', 'junkemail', 'localfailures', 'msgfolderroot', 'mycontacts', 'notes', 'outbox', 'peoplecentricconversationbuddies', 'peopleconnect', 'quickcontacts', 'recipientcache', 'recoverableitemsdeletions', 'recoverableitemspurges', 'recoverableitemsroot', 'recoverableitemsversions', 'relevantcontacts', 'searchfolders', 'sentitems', 'serverfailures', 'sharepointnotifications', 'syncissues', 'tasks', 'temporarysaves', 'todosearch', 'voicemail'] Can you try again, checking that the installed exchangelib has the patches? |
Hi @ecederstrand, This is my requirements.txt file:
This is the output of my pip install:
Then I ran the script again:
|
Great! No more The original bug report was for |
@ecederstrand If I just run
But if I run your script in #1301 (comment), I can get the result:
|
@quzhi1 Ok, well at least I can see from the stack trace that you got past the initial fetching of distinguished folders, which is good, and the |
@ecederstrand Sure.
|
Hmmm, why would the It's possible that the server for some reason does not like one or more of the additional fields that we request in the GetFolder call. Also, it would be nice to see the actual XML request that the server throws an error on. Can you run this and post the XML request that triggers the ErrorInvalidSchemaVersionForMailboxVersion error response? If the from exchangelib.folders import FolderCollection
from exchangelib.util import PrettyXmlHandler
logging.basicConfig(level=logging.DEBUG, handlers=[PrettyXmlHandler()])
for f in FolderCollection(account=account, folders=[account.root]).find_folders():
if f.name != "XrmInsights":
continue
fc = FolderCollection(account=account, folders=[f])
additional_fields = fc.get_folder_fields(target_cls=fc._get_target_cls())
list(fc.get_folders(additional_fields=set()))
for field in additional_fields:
try:
list(fc.get_folders(additional_fields={field}))
except Exception as e:
print(f"ERROR: GetFolder with field {field!r} failed: {e!r}")
list(fc.get_folders(additional_fields=additional_fields)) |
@ecederstrand This is the script I ran: https://github.com/quzhi1/EwsPlayground/blob/main/debugging_xrm_insights.py And this is the console output: https://github.com/quzhi1/EwsPlayground/blob/main/output.txt |
Thanks! In the FindFolder response, the folder is returned as: <t:Folder>
<t:FolderId Id="AQMkAExAAAA" ChangeKey="AABGS"/>
<t:DisplayName>XrmInsights</t:DisplayName>
<t:DistinguishedFolderId>XrmInsights</t:DistinguishedFolderId>
[...]
</t:Folder> but any attempt to call GetFolder with this DistinguishedFolderId value returns the SOAP error I don't have any solutions for this problem right now. |
In this case, can we hardcode the Although the response contains |
@quzhi1 A workaround would be to mark the folder to exclude GetFolder requests: from exchangelib.folders import NonDeletableFolder, NON_DELETABLE_FOLDERS
class XrmInsights(NonDeletableFolder):
get_folder_allowed = False
NON_DELETABLE_FOLDERS.append(XrmInsights)
account.root.tree() Your suggestion is an option for a more permanent solution, but the EWS docs aren't always totally up-to-date, and don't specify when there are differences between Exchange versions, so I'd like to avoid that solution if possible. |
For anyone else in this thread having the same issue, please post here whether you also only have trouble with the |
@ecederstrand I am still seeing the same version errors with this commit. Running this script: https://github.com/quzhi1/EwsPlayground/blob/main/debugging_find_folders.py Output:
Running this script: https://github.com/quzhi1/EwsPlayground/blob/main/debugging_xrm_insights.py Output: https://github.com/quzhi1/EwsPlayground/blob/main/output.txt |
Apologies for the delay in replying. I tried installing from commit be0cd9f and re-ran the test script but found I still got the same error message as before. I subsequently tried installing from commit 1e77961 and the test script produced far fewer errors, but there was still an invalid schema version error that caused my code to crash when I tried to access ERROR: GetFolder on folder 'calendarsearchcache' failed: ErrorInvalidSchemaVersionForMailboxVersion("Tried versions ('Exchange2015', 'Exchange2016', 'Exchange2015_SP1', 'Exchange2013_SP1', 'Exchange2013', 'Exchange2010_SP2', 'Exchange2010_SP1', 'Exchange2010', 'Exchange2007_SP1', 'Exchange2007') but all were invalid") I still got the same error after installing 17ea29a |
@laurachan That's unexpected. Can you please double check that your exchangelib does in fact contain 17ea29a, and whether |
ErrorInvalidSchemaVersionForMailboxVersion still occurred on calendarsearchcache after that. I also confirmed that both |
Never mind, I think the error might have been on my end and caused by accidentally having two versions of exchangelib present. After getting pip to uninstall exchangelib and then rerunning the command to install 17ea29a, the errors disappeared. Sorry about that! |
Glad to hear it works for you as well! |
with v5.4.0 the ErrorInvalidSchemaVersionForMailboxVersion vanishes at our end as well. thanks a lot @ecederstrand |
Describe the bug
When trying to access Exchange folders via
account.msg_folder_root.tree()
we run into this error message:exchangelib.errors.ErrorInvalidSchemaVersionForMailboxVersion: Tried versions ('Exchange2016', 'Exchange2015_SP1', 'Exchange2015', 'Exchange2013_SP1', 'Exchange2013', 'Exchange2010_SP2', 'Exchange2010_SP1', 'Exchange2010', 'Exchange2007_SP1', 'Exchange2007') but all were invalid
This worked with exchangelib v4.9.0 and now fails after updating to v5.2.1.
The Exchange server version comes back as "V2017_07_11" (15.2.1544.4). I also include the
ServerVersionInfo
response header in the log outputs below.The
GetFolder
call in folders/collections.py runs through when requesting foldersDistinguishedFolderId Id="root"
andDistinguishedFolderId Id="msgfolderroot"
. But then on the third call for the children of "msgfolderroot" it crashes with the above error, after retrieving a faulty xml response with anErrorInvalidRequest
.As build 15.2.1544.4 corresponds to a 2019 Exchange server version and the api version string for Exchange 2019 was changed from "Exchange2019" to "Exchange2016" between exchangelib version v4.9.0 and v5.2.1, could that change have caused this issue?
To Reproduce
You'll need an Exchange server running on version 15.2.1544.4. Then this code should produce the error:
Log output
Traceback:
ServerVersionInfo in response xml:
Faulty response xml:
Additional context
Python version: 3.12.1
exchangelib version: 5.2.1
Exchange server version: "V2017_07_11" (15.2.1544.4)
The text was updated successfully, but these errors were encountered: