Exchange ActiveSync for Zimbra Open Source Edition

Posted by

If you want to obtain Exchange ActiveSync ability on your Zimbra Open Source Edition, you can integrate Zimbra and Z-push + Zimbra Backend. With it, you can synchronize email, contacts, and calendars between Zimbra and your mobile device.

This article only for Zimbra that installing Single Server. If you have Zimbra with multi-server installation, I recommend you to install Z-push + Zimbra Backend on a separate server.

This guidance has been tested on Zimbra 8.8.12 – 8.8.15

# Install dependencies

For CentOS 7

yum install epel-release -y
yum install git php-cli php-soap php-process php-mbstring -y

For Ubuntu 16.04 and 18.04

apt update -y
apt install git php-cli php-soap php-cgi php-mbstring php-curl -y

Clone repo

git clone
cd zcs-zpush/

Create folder for log

mkdir /var/lib/z-push /var/log/z-push
chmod 755 /var/lib/z-push /var/log/z-push
chown zimbra:zimbra /var/lib/z-push /var/log/z-push

Save z-push folder on /opt/

cp -rvf z-push /opt/

Note : I use Asia/Jakarta as my Timezone. Please open /opt/z-push/config.php and adjust/change Asia/Jakarta to your Timezone

Create symlink

ln -sf /opt/z-push /opt/zimbra/jetty/webapps/

Save php script on /usr/bin

cp /usr/bin/
chmod +x /usr/bin/

Change publicHostname domain on your Zimbra into localhost

su - zimbra -c 'zmprov md yourzimbradomain.tld zimbraPublicServiceHostname localhost zimbraPublicServiceProtocol https'

Note : If you have more than 1 domain, and that domain want to use Exchange ActiveSync, you should run above command for each domains

# Backup and replace

For Zimbra 8.8.6

cp /opt/zimbra/jetty/etc/ /opt/zimbra/jetty/etc/
cp /opt/zimbra/jetty/etc/
chown zimbra.zimbra /opt/zimbra/jetty/etc/

For Zimbra 8.8.7

cp /opt/zimbra/jetty/etc/ /opt/zimbra/jetty/etc/
cp /opt/zimbra/jetty/etc/
chown zimbra.zimbra /opt/zimbra/jetty/etc/

For Zimbra 8.8.8 – Zimbra 8.8.12

cp /opt/zimbra/jetty/etc/ /opt/zimbra/jetty/etc/
cp /opt/zimbra/jetty/etc/
chown zimbra.zimbra /opt/zimbra/jetty/etc/

For Zimbra 8.8.15

cp /opt/zimbra/jetty/etc/ /opt/zimbra/jetty/etc/
cp /opt/zimbra/jetty/etc/
chown zimbra.zimbra /opt/zimbra/jetty/etc/

For Zimbra 9

cp /opt/zimbra/jetty/etc/ /opt/zimbra/jetty/etc/
cp /opt/zimbra/jetty/etc/
chown zimbra.zimbra /opt/zimbra/jetty/etc/

# Add zpush.ini into php

For CentOS 7

cp zpush.ini /etc/php.d/zpush.ini

For Ubuntu 16.04

cp zpush.ini /etc/php/7.0/cgi/conf.d/10-zpush.ini

For Ubuntu 18.04

cp zpush.ini /etc/php/7.2/cgi/conf.d/10-zpush.ini

Restart Zimbra Mailbox

su - zimbra -c 'zmmailboxdctl restart'

For testing, please access https://ip-of-zimbra/Microsoft-Server-ActiveSync from your browser. Log in with your Zimbra account. If it works, you can see the output as below. Or you can configure your mail apps on mobile devices and ensure choose exchange/activesync


  1. Hi,thank you for your information.

    I have something to ask you.

    Is there for ZCS8.8.5(universal ui unofficial)

  2. Hi Ahmad, your tutorials are great! Thank you. I’ve tried to get this work, but something is not right, the schedules and the e-mails not pushing to the phones. I’m using Ubuntu 18.04.03 with the latest Zimbra build.

    1. Hi Tamas,
      Please make sure your mobile phone :
      – Enable sync
      – Please choose Automatic (Push) on Sync frequency. This configuration is there on your Mail client apps

  3. I tried, but it does not work in Centos 7 and the latest version of zimbra

    HTTP ERROR 404

    Problem accessing /service/extension/zimbrasync. Reason:

    Not Found

  4. Dear,
    We are using single server, 8.8.15P3 on Centos 7.7 with 4 vCPU and 8GB RAM. Server will serve about 200-300 accounts. Do you think we can have z-push on this spec?
    Many thanks and best regards,

  5. Hello,

    Seems something wrong.

    I get :

    . * * Consult LICENSE file for details ************************************************/ ob_start(null, 1048576); // ignore user abortions because this can lead to weird errors – see ZP-239 ignore_user_abort(true); require_once ‘vendor/autoload.php’; if (!defined(‘ZPUSH_CONFIG’)) define(‘ZPUSH_CONFIG’, ‘config.php’); include_once(ZPUSH_CONFIG); // Attempt to set maximum execution time ini_set(‘max_execution_time’, SCRIPT_TIMEOUT); set_time_limit(SCRIPT_TIMEOUT); try { // check config & initialize the basics ZPush::CheckConfig(); Request::Initialize(); ZLog::Initialize(); ZLog::Write(LOGLEVEL_DEBUG,”——– Start”); ZLog::Write(LOGLEVEL_DEBUG, sprintf(“cmd=’%s’ devType=’%s’ devId=’%s’ getUser=’%s’ from=’%s’ version=’%s’ method=’%s'”, Request::GetCommand(), Request::GetDeviceType(), Request::GetDeviceID(), Request::GetGETUser(), Request::GetRemoteAddr(), @constant(‘ZPUSH_VERSION’), Request::GetMethod() )); // always request the authorization header if (! R………………..

    1. Hello Stiwans,
      Please make sure :
      – SELinux has been disabled
      – PHP dependencies have been installed
      – What your Zimbra and OS version?

      1. Hello Iman,
        I noticed that your z-push source version is 2.3.4, while there’s now v2.5.1 final available.
        I’m going to experiment the “source” way (i.e. procedure outlined on your article) replacing your z-push subdir with the updated source from here (plus, of course, the Zimbra backend v68).
        May I fork your GitHub repo for this activity?
        Additionally, I believe that it isn’t strictly necessary to set zimbraPublicServiceHostname to “localhost”, you should instead whitelist the server’s public IP address within the Zimbra’s DoSFilter configuration section, as explained here
        Does this sound correct to you?

        1. Hello Ferdinando,
          Sure. You can fork my GitHub repo and it’s open. zimbraPublicServiceHostname refers to the localhost because I define localhost on ZIMBRA_URL config. So, the log is clean and not appear warning about ZIMBRA_URL

          1. Yes, I noticed that, reviewing the various configurations files.
            I was only concerned (as a Zimbra newbie) about possible negative interactions with other Zimbra services of setting “public hostname” to localhost.

  6. Hello Iman,

    This solution for Exchange Active-Sync for Zimra open source is great help. However, one problem with setting the Hostname as “localhost” (zimbraPublicServiceHostname localhost) is that one of the Admin Zimlet (com_zimbra_viewmail) stopped working. It uses the Hostname to open the mailbox for a user and now it is unable to do so.
    Can you help solve this problem?

  7. Hi there thank you for the guide, as for the zpush version it seems that it’s on 2.3.4 the current version is 2.5 is there a possibility to upgrade it?

    1. Hello Farzad,
      Yes possible to upgrade. You can save zimbraBackend and config on z-push folder. Then upgrade z-push with the new version

  8. Thank you for the reply, as for the localhost i ran the command but how to revert it back? and whitelist ?

    su – zimbra -c ‘zmprov md zimbraPublicServiceHostname localhost zimbraPublicServiceProtocol https’

    Thank you

  9. Hi Iman,

    Your guide works fine and ActiveSync was set up correctly.

    I’m on version 8.8.15, but ActiveSync breaks when proxy port is changed from 443.

    I want to change proxy port to 9444 then use a reverse proxy to serve clients on port 443.

    Can you please help out.


    1. Hi Darren Ramen,
      In this article, ActiveSync listen on Jetty. It’s mean ActiveSync active on mailbox services. If you have reverse proxy, you can try pointing to port 8080 or 8443 where service mailbox listen

  10. Hi Iman,

    Thanks for the instructions for setting up Activesync for Zimbra! Iphone mail/calender apps work line a charm.

    Do you know if Outlook App for iPhone is supported? The only error I get is “Can not sign in”. I’m using Patch 8.8.15_P8 on Ubuntu 18.04.4 64b.

  11. Hi Iman,

    Thank you for this nice post.
    I configured and it worked well in my environment. However, it seems the internal GAL is not syncing with PC Outlook. At the same time, email contact is syncing properly in mobile default app and webmail.
    Could you please help me on this?

  12. Morning Iman,

    The best informative guide I have seen out there. Great work.
    Just a quick question, I noticed z-push showing zimbra IP for all the devices connected via activesysnc rather than the actual IP. This makes it tricky to implement Fail2Ban etc.
    In z-push “config.php” I have included define(‘HTTP_X_FORWARDED_FOR’, ‘HTTP_X_REAL_IP’) or define(‘USE_X_FORWARDED_FOR_HEADER’, true); however I have not been able to get real IP of the devices.
    Do you have any trick up your sleeve how to fix this?
    Thanks Mate.

    1. Hi Chris,
      Please run the following command zmprov mcf +zimbraMailTrustedIP +zimbraMailTrustedIP {IP of nginx-1}
      zmmailboxdctl restart

      1. Hi Iman,
        Tried that but still showing the local IP address of zimbra server and not real IP address of the device.

      2. Thank you for the highest quality article.

        What parameter should I use in config.php to have the real ip?
        I tried in some ways and I couldn’t.
        Thank you

        1. Hi, I think it’s a bug of z-push, I use z-push 2.6.2 and zimbrabackend 71 for zimbra 8.8.15.
          I also set the define(‘USE_X_FORWARDED_FOR_HEADER’, true), but always not working.
          So I fix the file like below, and it’s working now.

          In the /opt/z-push/lib/request/request.php, around line 130, replace REMOTE_ADDR to HTTP_X_FORWARDED_FOR

          //self::$remoteAddr = self::filterIP($_SERVER[“REMOTE_ADDR”]);
          self::$remoteAddr = self::filterIP($_SERVER[“HTTP_X_FORWARDED_FOR”]);

  13. Can you help me resolve this?

    I am getting this error

    Problem accessing /z-push/index.php. Reason:

    Failed to exec CGI

    I am running this on CentOS 8 and Zimbra 9 OSS

  14. Hi Ahmad, i tried to install Z-Push on my 8.8.15 Machine but i can’t get it work 🙁
    When i try to login all i get is:

    Z-Push – Open Source ActiveSync
    Version 2.3.4
    Access denied. Please send authorisation information


    [FATAL] [unknown] Exception: (AuthenticationRequiredException) – Access denied. Please send authorisation information
    Zimbra->Logon(): END Logon – Proxy Error { connected = false }
    25/08/2020 22:58:10 [30946] [ INFO] […] AuthenticationRequiredException: Access denied. Proxy unable to initiate a session on user mailbox server – code: 0 – file: /opt/z-push/backend/zimbra/zimbra.php:1208

    I hope you have an idea. I use Ubuntu 18.04 with php 7.4

  15. Hi Iman,

    Your guide works just fine with ActiveSync (Outlook mobile and Windows client) so far using Zimbra OSE 8.8.15 on Ubuntu 18.04

    Trying make autodiscover to work but my getting:

    Problem accessing /z-push/index.php. Reason:

    Failed to exec CGI

    Any hints?

    1. Hi Antonio Filho,
      Autodiscover does not work for this guidance. However, you can try to modify Z-Push to support it. I haven’t try Autodiscover

  16. Hi! I installed z-push according to your instructions, please tell me how to set the limit for sending attachments. Emails with 20MB attachments remain in outgoing folder Outlook

    1. Hi Maxim,
      1. You should increase via Zimbra Admin | Configure | Global Settings | MTA | Maximum Message Size
      2. You can increase in php.ini

      1. Hi Iman, thanks for reply. I set zimbraMtaMaxMessageSize to 40960 and change php.ini (/etc/php.ini and /opt/zimbra/conf/php.ini) parameters upload_max_filesize and post_max_size to 40M. After that I run zmcontrol restart but I cannot sent 18Mb attachment from outlook, message stay at outgoing folder

        1. Edit /opt/z-push/policies.ini

          ; The maximum attachment size in bytes as determined by security policy.
          maxattsize = ‘62914560’

          use for 60MB

  17. Hello

    Is it possible get running z-push without Zimbra Proxy service? I have few users only. No proxy needed.

      1. I got it working finally.
        But I found that GAL and Calendars do not appear in Outlook 2016. If I understood correctly only shared contacts and calendars (folders) will work. Is it true?

        Thank you for help!

      1. I already install 9.0 , I try to install but , not working,

        HTTP ERROR 500

        Problem accessing /z-push/index.php. Reason:

        Failed to exec CGI

        Do you suggest using 9.0 ?

  18. hi, I installed on: “centos 7 zimbra 8.8.15” according to your description, but whatever I do I get an error 500
    HTTP ERROR 500
    Problem accessing /z-push/index.php.
    why is this happening?

      1. Hi Iman,
        I have enabled z-push.log debugging mode:
        [DEBUG] [#unknown] ——– Start
        [DEBUG] [#unknown] cmd=” devType=” devId=” getUser=’unknown’ from=’*MYSERVER_IP*’ version=’GIT’ method=’GET’
        [ INFO] [#unknown] AuthenticationRequiredException: Access denied. Please send authorisation information – code: 0 – file: /opt/z-push/src/index.php:56
        [ INFO] [#unknown] User-agent: ‘unknown’
        [FATAL] [#unknown] Exception: (AuthenticationRequiredException) – Access denied. Please send authorisation information
        [DEBUG] [#unknown] ZPush::PrintZPushLegal()
        [DEBUG] [#unknown] InterProcessData:__construct type: ”
        [DEBUG] [#unknown] TopCollector(): Initialized mutexid Resource id #43 and memid Resource id #44.
        [DEBUG] [#unknown] TopCollector initialised with IPC provider ‘IpcSharedMemoryProvider’ with type ’20’
        [ INFO] [#unknown] cmd=” memory=’2.29 MiB/2.75 MiB’ time=’0.01s’ devType=” devId=” getUser=’unknown’ from=’*MYSERVER_IP*’ idle=’0s’ version=’GIT’ method=’GET’ httpcode=’401′
        [DEBUG] [#unknown] ——– End
        INFO [qtp1225197672-128:https://*MYSERVER*/favicon.ico%5D [] AuthProvider – Adding auth provider: zimbra com.zimbra.cs.service.ZimbraAuthProvider
        INFO [qtp1225197672-128:https://*MYSERVER*/favicon.ico%5D [] AuthProvider – Adding auth provider: sampleoauth com.zimbra.cs.service.ZimbraAuthProviderForOAuth
        php -v
        PHP 5.4.16 (cli) (built: Apr 1 2020 04:07:17)
        Copyright (c) 1997-2013 The PHP Group
        Zend Engine v2.4.0, Copyright (c) 1998-2013 Zend Technologies

  19. Hi Iman,
    Thank you for the update on Zimbra 9 OSE! In our case, EAS on phone working for the primary mailbox of users. However, users with shared mailboxes and personas cannot send mail using the persona and cannot access the shared inbox. Is this the normal behavior of EAS? Can you please help with this?

  20. Hello,
    In Oracle Linux 8 – Zimbra 8.8.15
    HTTP ERROR 500

    Problem accessing /z-push/index.php. Reason:

    Failed to exec CGI

    PHP 7.2.24
    Does anyone have any idea what it might be?

  21. Hello
    im experience whit z-push in another company. Now I install whit this guide but, y can’t see the original IP in the log /var/log/z-push or /opt/zimbra/log/audit.log, only see ip of server.

    Can guide how can I see ?

    Thank you

        1. Sure!

          // When accessing through a proxy, the “X-Forwarded-For” header contains the original remote IP
          define(‘USE_X_FORWARDED_FOR_HEADER’, false);

          change for

          // When accessing through a proxy, the “X-Forwarded-For” header contains the original remote IP
          define(‘USE_X_FORWARDED_FOR_HEADER’, true);

  22. I tried, but it does not work in Centos 7 and the latest version of zimbra
    HTTP ERROR 404
    Problem accessing /service/extension/zimbrasync. Reason:
    Not Found
    my zimbra version: Release 8.8.15_GA_3869.RHEL7_64_20190917004220 RHEL7_64 FOSS edition, Patch 8.8.15_P27
    i followed exactly same steps for Backup and replace For Zimbra 8.8.15

  23. Hi Iman,
    We are using Zimbra 8.8.15 with Z-Push and it looks all working good.
    However, it seems some users can only sync 1000 email per folder but some are 2000 email per folder.
    How we can sync ALL email per folder like IMAP?
    Appreciate your early reply .
    Many thanks !!

  24. Hello
    Centos 9 zpush 2.3 install

    08/12/2021 23:08:55 [358791] [FATAL] [xxxxx.xxxxxx.xxxx] Exception: (WBXMLException) – Unknown error in SendMail->Handle()
    08/12/2021 23:08:55 [358791] [FATAL] [xxxxx.xxxxxx.xxxx] Exception: (WBXMLException) – Unknown error in SendMail->Handle()
    08/12/2021 23:08:55 [358791] [FATAL] [xxxxx.xxxxxx.xxxx] Request could not be processed correctly due to a WBXMLException. Please report this including the ‘WBXML debug data’ logged. Be aware that the debug data could contain confidential information.
    08/12/2021 23:08:55 [358791] [FATAL] [xxxxx.xxxxxx.xxxx] Request could not be processed correctly due to a WBXMLException. Please report this including the ‘WBXML debug data’ logged. Be aware that the debug data could contain confidential information.

  25. Halo Iman,

    great post.
    Btw, i don’t know if you still read this, but I have question.

    After I followed your instruction, the zmmailboxctl doesn’t start and I can’t access Zimbra web GUI. basically, zimbra service is down. I tried to zmcontrol restart and anything but nothing works..

    After troubleshooting, I found out the jetty file that causes this (I don’t know which part) because after we replace the jetty file from you with the original one, the zimbra server can be accessed again.

    Any advice on why that’s happening? Because I’ve tried it before on lab and it works perfectly just fine. And now, when the zimbra mail already up on production, I need to use activesync but it doesn’t work.

    By the way i use zimbra 8.8.15.

    Thankyou, and i hope you can answer this

  26. Hello, I have a problem under php8.1, the error is:
    06/09/2022 11:43:04 [379496] [FATAL] Fatal error: /z-push/lib/wbxml/wbxmlencoder.php:174 – Uncaught TypeError: stream_filter_append(): Argument #1 ($stream) must be of type resource, string given in /z-push/lib/wbxml/wbxmlencoder.php:174
    Stack trace:
    #0 /z-push/lib/wbxml/wbxmlencoder.php(174): stream_filter_append()
    #1 /z-push/lib/core/streamer.php(327): WBXMLEncoder->contentStream()
    #2 /z-push/lib/core/streamer.php(252): Streamer->Encode()
    #3 /z-push/lib/core/streamimporter.php(171): Streamer->Encode()
    #4 /z-push/lib/default/diffbackend/exportchangesdiff.php(166): ImportChangesStream->ImportMessageChange()
    #5 /z-push/lib/request/sync.php(1199): ExportChangesDiff->Synchronize()
    #6 /z-push/lib/request/sync.php(956): Sync->syncFolder()
    #7 /z-push/lib/request/requestprocessor.php(116): Sync->Handle()
    #8 /z-push/index.php(107): RequestProcessor::HandleRequest()
    #9 {main}
    thrown (1)

  27. Hello,
    Ubuntu 18, Zimbra 8.8.15
    After installing zimbra crashes, the zmmailboxdctl service starts and then stops. Restarting brings the same.
    Restoring the file helps, but then no z-push, of course.
    Are you willing to help solving this? I have multiple domains and this solution would be great, if it worked.
    Thank you in advance!

        1. Hi, after applying patch 33 for 8.8.15 i face the same problem and I had to disable z-push to make the server work.
          moreover i fount this errors in the zmmailboxd.out file
          zmmailboxd.out:2023-01-10 18:33:40.952:WARN:oejs.SecurityHandler:main: ServletContext@o.e.j.w.WebAppContext@57d7f8ca{php,/z-push,file:///opt/z-push/,STARTING}{/opt/zimbra/mailboxd/webapps/z-push} has uncovered http methods for path: /
          zmmailboxd.out:2023-01-10 18:33:40.961:INFO:oejsh.ContextHandler:main: Started o.e.j.w.WebAppContext@57d7f8ca{php,/z-push,file:///opt/z-push/,AVAILABLE}{/opt/zimbra/mailboxd/webapps/z-push}

  28. Hello pro,
    I install on Zimbra 8.8.15, Ubuntu 20.04 , run the web I get this error:
    #HTTP ERROR 502
    #Problem accessing ZCS upstream server. Cannot connect to the ZCS upstream server. Connection is refused.
    #Possible reasons:
    #upstream server is unreachable
    #upstream server is currently being upgraded
    #upstream server is down
    #Please contact your ZCS administrator to fix the problem.
    #Powered by Nginx-Zimbra://
    Can you help me ?
    Best regards

  29. Hi there,

    Very nice tool working great thank you.

    Is there a way to enable/disable access for Zimbra users to ActiveSync/Mapi ? (tried in account => features but it’s not working)


  30. Ubuntu 20 and Zimbra 9 – multiple errors:
    2023-11-30 21:35:28,973 WARN [main] [] ephemeral – Replacing ephemeral factory class ‘com.zimbra.cs.ephemeral.LdapEphemeralStore$Factory’ registered for ‘ldap’ with ‘com.zimbra.cs.ephemeral.LdapEphemeralStore$Factory’
    2023-11-30 21:35:28,978 WARN [main] [] extensions – no Zimbra-Extension-Class found, ignored: /opt/zimbra/lib/ext/twofactorauth
    2023-11-30 21:35:28,979 WARN [main] [] extensions – no Zimbra-Extension-Class found, ignored: /opt/zimbra/lib/ext/mitel
    2023-11-30 21:35:28,979 WARN [main] [] extensions – no Zimbra-Extension-Class found, ignored: /opt/zimbra/lib/ext/convertd
    2023-11-30 21:35:29,030 WARN [main] [] ephemeral – Replacing ephemeral factory class ‘com.zimbra.ssdb.SSDBEphemeralStore$Factory’ registered for ‘ssdb’ with ‘com.zimbra.ssdb.SSDBEphemeralStore$Factory’
    2023-11-30 21:35:31,293 WARN [main] [] AnnotatedArgumentBuilder – No explicit argument name given and the parameter name lost in compilation: public abstract boolean org.w3c.dom.TypeInfo.isDerivedFrom(java.lang.String,java.lang.String,int)#java.lang.String arg0. For details and possible solutions see

    mailboxd stops running and that is it.
    Is there a way to correct it?
    Thank you in advance!

  31. Hello, thank you for the answer. Custom nginx does not work either. Actually of 2 Zimbra servers I administer only on one this method works. Nginx version does not work on either of the servers.

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.