I've been working on this problem for years with no success (I gave up a while back and just hoped Gmail would eventually "learn" that messages from one of my servers wasn't spam, but that apparently never happened).
I'm a game developer who runs forums and download servers for my customers. As part of my operation, I need to sent people emails, often at their request. For example, password-reset emails from my forums. This isn't a "bulk" mailing situation, nor is my server sending out lots of email.
I have two servers, both with the same hosting provider.
One is in a shared hosting environment, where I get a subdir and my domain name is resoloved using virtual hosting. Emails from that server have always been received just fine (though I didn't set up the email system, nor do I have much control over it).
The other is a VPS that I manage. I have my own IP address there, and have full control over everything. From the VPS, I've never been able to send emails that Gmail doesn't see as spam. I've set up spf, dkim, and all tests seem to pass, even according to Gmail when I "view original message". I'm not on any blacklists that I can see. And I've tested it with "personal" messages that don't even contain any links or images. Still spam.
HOWEVER, I just ran a controlled test (same message sent from webmail on each of these servers), and the headers on the non-spam server are substantially different. It looks like the mail is being sent through a mail relay. Maybe that helps somehow (if the mail relay is trusted, I guess?) Here's the raw message that Gmail sees as non-spam:
Delivered-To: jasonrohrer@gmail.com
Received: by 10.182.233.195 with SMTP id ty3csp518065obc;
Tue, 14 Feb 2017 22:46:33 -0800 (PST)
X-Received: by 10.99.171.5 with SMTP id p5mr36545947pgf.182.1487141193736;
Tue, 14 Feb 2017 22:46:33 -0800 (PST)
Return-Path: <jason@northcountrynotes.org>
Received: from cross.birch.relay.mailchannels.net (cross.birch.relay.mailchannels.net. [23.83.209.46])
by mx.google.com with ESMTPS id m10si2359238pln.229.2017.02.14.22.46.33
for <jasonrohrer@gmail.com>
(version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128);
Tue, 14 Feb 2017 22:46:33 -0800 (PST)
Received-SPF: pass (google.com: domain of jason@northcountrynotes.org designates 23.83.209.46 as permitted sender) client-ip=23.83.209.46;
Authentication-Results: mx.google.com;
spf=pass (google.com: domain of jason@northcountrynotes.org designates 23.83.209.46 as permitted sender) smtp.mailfrom=jason@northcountrynotes.org
X-Sender-Id: asmallorange|x-authuser|jason@northcountrynotes.org
Received: from relay.mailchannels.net (localhost [127.0.0.1]) by relay.mailchannels.net (Postfix) with ESMTP id F1F6E1412C0 for <jasonrohrer@gmail.com>; Wed, 15 Feb 2017 06:46:32 +0000 (UTC)
Received: from rory.asoshared.com (unknown [100.96.13.116]) by relay.mailchannels.net (Postfix) with ESMTPA id 7722A1413D6 for <jasonrohrer@gmail.com>; Wed, 15 Feb 2017 06:46:32 +0000 (UTC)
X-Sender-Id: asmallorange|x-authuser|jason@northcountrynotes.org
Received: from rory.asoshared.com (rory.asoshared.com [172.20.104.49]) (using TLSv1.2 with cipher DHE-RSA-AES256-GCM-SHA384) by 0.0.0.0:2500 (trex/5.7.19); Wed, 15 Feb 2017 06:46:32 +0000
X-MC-Relay: Neutral
X-MailChannels-SenderId: asmallorange|x-authuser|jason@northcountrynotes.org
X-MailChannels-Auth-Id: asmallorange
X-MC-Loop-Signature: 1487141192688:2323082264
X-MC-Ingress-Time: 1487141192688
Received: from [::1] (port=55001 helo=northcountrynotes.org) by rory.asoshared.com with esmtpa (Exim 4.87) (envelope-from <jason@northcountrynotes.org>) id 1cdtME-00089O-RN for jasonrohrer@gmail.com; Wed, 15 Feb 2017 01:46:31 -0500
Received: from 50.1.19.178 ([50.1.19.178])
(SquirrelMail authenticated user jason@northcountrynotes.org)
by northcountrynotes.org with HTTP;
Wed, 15 Feb 2017 01:46:30 -0500
Message-ID: <a6c63634f6f368814f401e02ef2df1fb.squirrel@northcountrynotes.org>
Date: Wed, 15 Feb 2017 01:46:30 -0500
Subject: Hello from an old friend
From: jason@northcountrynotes.org
To: jasonrohrer@gmail.com
User-Agent: SquirrelMail/1.5.2 [SVN]
MIME-Version: 1.0
Content-Type: text/plain;charset=utf-8
Content-Transfer-Encoding: 8bit
X-AuthUser: jason@northcountrynotes.org
Hey Jason, my old friend. Remember when we went to school together so
long ago at Cornell. Boy! Those were the days. Hit me back if you want
to chat.
Justin J.
And here's the raw message from the VPS server, from which Gmail always puts messages in the spam folder:
Delivered-To: jasonrohrer@gmail.com
Received: by 10.182.233.195 with SMTP id ty3csp516102obc;
Tue, 14 Feb 2017 22:33:25 -0800 (PST)
X-Received: by 10.36.198.133 with SMTP id j127mr7649805itg.72.1487140405772;
Tue, 14 Feb 2017 22:33:25 -0800 (PST)
Return-Path: <jason@thecastledoctrine.net>
Received: from server.thecastledoctrine.net (server.thecastledoctrine.net. [108.165.22.58])
by mx.google.com with ESMTPS id 127si5199936itx.63.2017.02.14.22.33.25
for <jasonrohrer@gmail.com>
(version=TLS1 cipher=AES128-SHA bits=128/128);
Tue, 14 Feb 2017 22:33:25 -0800 (PST)
Received-SPF: pass (google.com: domain of jason@thecastledoctrine.net designates 108.165.22.58 as permitted sender) client-ip=108.165.22.58;
Authentication-Results: mx.google.com;
dkim=pass header.i=@thecastledoctrine.net;
spf=pass (google.com: domain of jason@thecastledoctrine.net designates 108.165.22.58 as permitted sender) smtp.mailfrom=jason@thecastledoctrine.net
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=thecastledoctrine.net; s=default; h=Content-Transfer-Encoding:Content-Type:MIME-Version:To:From:Subject:Date:Message-ID; bh=7hycuruqtuxJJjoFV/Gyd/n8jFs9UDvFVpJOWI96Abw=; b=yPnvk3ZVtOiXNFo9+zRP0mEdKWoahLgA4Au/GeUrmKC6uJiB9A6VJyEudRHdhidBiOalf30exm6gk+7+To0y1XEMwGzHpch8I32RY85qrJmzptX8mrqBBRC9Q51hfWCTcgmSXwS1YsiIgJYu96GSw+PZ2lgPAfOkZaR+i6lrIKs=;
Received: from localhost ([127.0.0.1]:54405 helo=thecastledoctrine.net) by server.thecastledoctrine.net with esmtpa (Exim 4.85) (envelope-from <jason@thecastledoctrine.net>) id 1cdt9X-0001bg-M5 for jasonrohrer@gmail.com; Wed, 15 Feb 2017 06:33:23 +0000
Received: from 50.1.19.178 ([50.1.19.178])
(SquirrelMail authenticated user jason@thecastledoctrine.net)
by thecastledoctrine.net with HTTP;
Wed, 15 Feb 2017 06:33:23 -0000
Message-ID: <bb9ed865cadaedf1c99097d576ae7ac9.squirrel@thecastledoctrine.net>
Date: Wed, 15 Feb 2017 06:33:23 -0000
Subject: Hello from an old friend
From: jason@thecastledoctrine.net
To: jasonrohrer@gmail.com
User-Agent: SquirrelMail/1.5.2 [SVN]
MIME-Version: 1.0
Content-Type: text/plain;charset=iso-8859-1
Content-Transfer-Encoding: 8bit
X-AntiAbuse: This header was added to track abuse, please include it with any abuse report
X-AntiAbuse: Primary Hostname - server.thecastledoctrine.net
X-AntiAbuse: Original Domain - gmail.com
X-AntiAbuse: Originator/Caller UID/GID - [47 12] / [47 12]
X-AntiAbuse: Sender Address Domain - thecastledoctrine.net
X-Get-Message-Sender-Via: server.thecastledoctrine.net: authenticated_id: jason@thecastledoctrine.net
Hey Jason, my old friend. Remember when we went to school together so
long ago at Cornell. Boy! Those were the days. Hit me back if you want
to chat.
Justin J.
I'm guessing that I'm missing something simple here.
Update:
Here's another message sent from the VPS that is marked as spam. This is a message generated by one of my PHP scripts (a download server, sending someone the download key that they paid for). It contains links, but when an identical message is sent from the shared server, it is not spam.
Delivered-To: jasonrohrer@gmail.com
Received: by 10.182.233.195 with SMTP id ty3csp529399obc;
Tue, 14 Feb 2017 23:55:38 -0800 (PST)
X-Received: by 10.36.161.70 with SMTP id n6mr7354632iti.76.1487145338304;
Tue, 14 Feb 2017 23:55:38 -0800 (PST)
Return-Path: <jason@thecastledoctrine.net>
Received: from server.thecastledoctrine.net (server.thecastledoctrine.net. [108.165.22.58])
by mx.google.com with ESMTPS id w204si3392935itc.67.2017.02.14.23.55.37
for <jasonrohrer@gmail.com>
(version=TLS1 cipher=AES128-SHA bits=128/128);
Tue, 14 Feb 2017 23:55:38 -0800 (PST)
Received-SPF: pass (google.com: domain of jason@thecastledoctrine.net designates 108.165.22.58 as permitted sender) client-ip=108.165.22.58;
Authentication-Results: mx.google.com;
dkim=pass header.i=@thecastledoctrine.net;
spf=pass (google.com: domain of jason@thecastledoctrine.net designates 108.165.22.58 as permitted sender) smtp.mailfrom=jason@thecastledoctrine.net
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=thecastledoctrine.net; s=default; h=Message-Id:Date:Subject:To:From; bh=GFDUYdq+5oW7xSkEaXekddRXEY2zhMAKlOU/+v0g27c=; b=s3kENICTVFbW8saQ0ya7bh1V+XIb9a4NCQlUghvQHa/52Rw40V3e6a33jRgJCJx2v9kc4NhLDjUM6Q/upbLh6kRGWwTCotG7bIrLlhlKGnLgNaraffq2kVuNkTYi+auts7QzofJBs3Gw1ctvYJf7LH3fxVgiEqUK06P2Q0Dnim4=;
Received: from [108.165.22.59] (port=39156 helo=localhost) by server.thecastledoctrine.net with esmtpsa (TLSv1:DHE-RSA-AES256-SHA:256) (Exim 4.85) (envelope-from <jason@thecastledoctrine.net>) id 1cduR6-0000KN-OG for jasonrohrer@gmail.com; Wed, 15 Feb 2017 07:55:36 +0000
From: Jason Rohrer <jason@thecastledoctrine.net>
To: jasonrohrer@gmail.com
Subject: Your [The Castle Doctrine] download is ready
Date: Wed, 15 Feb 2017 02:55:35 -0500
Message-Id: <58a40977f2d47@thecastledoctrine.net>
X-AntiAbuse: This header was added to track abuse, please include it with any abuse report
X-AntiAbuse: Primary Hostname - server.thecastledoctrine.net
X-AntiAbuse: Original Domain - gmail.com
X-AntiAbuse: Originator/Caller UID/GID - [47 12] / [47 12]
X-AntiAbuse: Sender Address Domain - thecastledoctrine.net
X-Get-Message-Sender-Via: server.thecastledoctrine.net: authenticated_id: jason@thecastledoctrine.net
Jason Rohrer Gmail:
Keep your ticket ID secure, because it is your sole way of accessing your account on the game server.
Your can now access your download at:
http://thecastledoctrine.net/ts/server.php?action=show_downloads&ticket_id=8G5QX
You can also access your download manually by entering your ticket 8G5QX here:
http://thecastledoctrine.net
And no, this is NOT the same question. Here I have two example non-bulk emails, one delivered, and one not. The usual answers are of no use, because I'm already doing all of that stuff.