diff --git a/plugins/audioscrobbler/rb-audioscrobbler-account.c b/plugins/audioscrobbler/rb-audioscrobbler-account.c
index d610734..9b8b619 100644
--- a/plugins/audioscrobbler/rb-audioscrobbler-account.c
+++ b/plugins/audioscrobbler/rb-audioscrobbler-account.c
@@ -64,6 +64,48 @@ struct _RBAudioscrobblerAccountPrivate
 	SoupSession *soup_session;
 };
 
+struct lastfm_error_message {
+  guint code;
+  gchar *message;
+};
+
+/* Source: http://www.last.fm/api/errorcodes */
+struct lastfm_error_message lastfm_error_messages[] = {
+  {  1, "This error does not exist" },
+  {  2, "Invalid service -This service does not exist" },
+  {  3, "Invalid Method - No method with that name in this package" },
+  {  4, "Authentication Failed - You do not have permissions to access the service" },
+  {  5, "Invalid format - This service doesn't exist in that format" },
+  {  6, "Invalid parameters - Your request is missing a required parameter" },
+  {  7, "Invalid resource specified" },
+  {  8, "Operation failed - Most likely the backend service failed. Please try again." },
+  {  9, "Invalid session key - Please re-authenticate" },
+  {  10, "Invalid API key - You must be granted a valid key by last.fm" },
+  {  11, "Service Offline - This service is temporarily offline. Try again later." },
+  {  12, "Subscribers Only - This station is only available to paid last.fm subscribers" },
+  {  13, "Invalid method signature supplied" },
+  {  14, "Unauthorized Token - This token has not been authorized" },
+  {  15, "This item is not available for streaming." },
+  {  16, "The service is temporarily unavailable, please try again." },
+  {  17, "Login: User requires to be logged in" },
+  {  18, "Trial Expired - This user has no free radio plays left. Subscription required." },
+  {  19, "This error does not exist" },
+  {  20, "Not Enough Content - There is not enough content to play this station" },
+  {  21, "Not Enough Members - This group does not have enough members for radio" },
+  {  22, "Not Enough Fans - This artist does not have enough fans for for radio" },
+  {  23, "Not Enough Neighbours - There are not enough neighbours for radio" },
+  {  24, "No Peak Radio - This user is not allowed to listen to radio during peak usage" },
+  {  25, "Radio Not Found - Radio station not found" },
+  {  26, "API Key Suspended - This application is not allowed to make requests to the web services" },
+  {  27, "Deprecated - This type of request is no longer supported" },
+  {  29, "Rate Limit Exceded - Your IP has made too many requests in a short period, exceeding our API guidelines" },
+};
+
+/* Retry only on the following error codes for last.fm.  */
+guint lastfm_retry_error_codes[] = {
+  8, 11, 16
+};
+
 #define RB_AUDIOSCROBBLER_ACCOUNT_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), RB_TYPE_AUDIOSCROBBLER_ACCOUNT, RBAudioscrobblerAccountPrivate))
 
 static void          rb_audioscrobbler_account_class_init (RBAudioscrobblerAccountClass *klass);
@@ -90,10 +132,16 @@ static void          request_token (RBAudioscrobblerAccount *account);
 static void          got_token_cb (SoupSession *session,
                                    SoupMessage *msg,
                                    gpointer user_data);
+static void          lastfm_wait_for_authentication(gpointer user_data);
+static void          lastfm_authentication_completed_cb(GtkDialog *dialog,
+							gint response_id,
+							gpointer user_data);
 static gboolean      request_session_key_timeout_cb (gpointer user_data);
 static void          got_session_key_cb (SoupSession *session,
                                          SoupMessage *msg,
                                          gpointer user_data);
+static gboolean      isLastFm(RBAudioscrobblerAccount *account);
+
 enum
 {
 	PROP_0,
@@ -482,6 +530,12 @@ cancel_session (RBAudioscrobblerAccount *account)
 	}
 }
 
+static gboolean
+isLastFm(RBAudioscrobblerAccount *account)
+{
+       return (g_strcmp0(rb_audioscrobbler_service_get_name (account->priv->service), LASTFM_NAME) == 0);
+}
+
 static void
 request_token (RBAudioscrobblerAccount *account)
 {
@@ -560,14 +614,19 @@ got_token_cb (SoupSession *session, SoupMessage *msg, gpointer user_data)
 				               account->priv->auth_token);
 			rb_debug ("sending user to %s", url);
 			gtk_show_uri (NULL, url, GDK_CURRENT_TIME, NULL);
-
-			/* add timeout which will ask for session key */
-			account->priv->session_key_timeout_id =
-				g_timeout_add_seconds (SESSION_KEY_REQUEST_TIMEOUT,
-					               request_session_key_timeout_cb,
-					               account);
-
 			g_free (url);
+
+			/* For Last.fm, do not request a session key unless the token is authenticated, */
+			/* failing which the webservice invalidates the token causing 'token expired' errors. */
+			if (isLastFm (account)) {
+			    lastfm_wait_for_authentication (account);
+			} else {
+			    /* add timeout which will ask for session key */
+			    account->priv->session_key_timeout_id =
+			      g_timeout_add_seconds (SESSION_KEY_REQUEST_TIMEOUT,
+						     request_session_key_timeout_cb,
+						     account);
+			}
 		} else {
 			rb_debug ("error retrieving auth token: %s",
 			          json_object_get_string_member (root_object, "message"));
@@ -589,6 +648,66 @@ got_token_cb (SoupSession *session, SoupMessage *msg, gpointer user_data)
 	g_object_unref (parser);
 }
 
+static void
+lastfm_wait_for_authentication(gpointer user_data)
+{
+	RBAudioscrobblerAccount *account;
+
+	GtkWidget *icon;
+	GtkWidget *label;
+	GtkWidget *content;
+	GtkWidget *wait_dialog;
+	gchar *icon_name;
+	
+	const gchar *message = "Click \"OK\" once you have granted access to rhythmbox in your Last.fm account";
+	
+	account = RB_AUDIOSCROBBLER_ACCOUNT (user_data);
+
+	GtkDialogFlags flags = GTK_DIALOG_MODAL|GTK_DIALOG_DESTROY_WITH_PARENT;
+	wait_dialog = gtk_dialog_new_with_buttons (_("Waiting for Last.fm authentication ..."),
+						   NULL,
+						   flags,
+						   _("_OK"),
+						   GTK_RESPONSE_OK,
+						   NULL);
+
+	g_signal_connect_object (G_OBJECT (wait_dialog),
+				 "response",
+				 G_CALLBACK (lastfm_authentication_completed_cb),
+				 account, 0);
+
+	// Setup content area
+	content = gtk_dialog_get_content_area (GTK_DIALOG (wait_dialog));
+	gtk_box_set_spacing (GTK_BOX (content), 10);
+	icon_name = g_strconcat (rb_audioscrobbler_service_get_name (account->priv->service), "-symbolic", NULL);
+	icon = gtk_image_new_from_icon_name(icon_name, GTK_ICON_SIZE_DIALOG);
+	label = gtk_label_new (message);
+
+	gtk_container_add (GTK_CONTAINER (content), icon);
+	gtk_container_add (GTK_CONTAINER (content), label);
+
+	// Display wait dialog
+	gtk_container_set_border_width (GTK_CONTAINER (wait_dialog), 5);
+	gtk_window_set_resizable (GTK_WINDOW(wait_dialog), FALSE);
+	gtk_widget_show_all (wait_dialog);
+
+	g_free(icon_name);
+}
+
+static void
+lastfm_authentication_completed_cb(GtkDialog *dialog,
+				   gint response_id,
+				   gpointer user_data)
+{
+	RBAudioscrobblerAccount *account;
+
+	account = RB_AUDIOSCROBBLER_ACCOUNT (user_data);
+	gtk_widget_destroy (GTK_WIDGET (dialog));
+
+	/* Request a session key, now we are authenticated. */
+	request_session_key_timeout_cb(account);
+}
+
 static gboolean
 request_session_key_timeout_cb (gpointer user_data)
 {
@@ -674,21 +793,44 @@ got_session_key_cb (SoupSession *session, SoupMessage *msg, gpointer user_data)
 			g_signal_emit (account, rb_audioscrobbler_account_signals[LOGIN_STATUS_CHANGED],
 				       0, account->priv->login_status);
 		} else {
+		        int i;
 			int code;
 			const char *message;
 
 			code = json_object_get_int_member (root_object, "error");
 			message = json_object_get_string_member (root_object, "message");
 
+			rb_debug ("getSession returned ( %d : %s )", code, message);
+			
 			switch (code) {
 			case 14:
-				rb_debug ("auth token has not been authorised yet. will try again");
+			        /* Last.fm case */
+			        if (isLastFm (account)) {
+				  /* go back to being logged out */
+				  rb_debug ("auth token has not been authorised. logging out");
+				  rb_audioscrobbler_account_logout (account);
+				} else {
+				  rb_debug ("auth token has not been authorised yet. will try again");
+				}
 				break;
 			default:
+
+			        /* Last.fm case */
+			        /* servers are sometimes busy causing retry errors. */
+			        if (isLastFm (account)) {
+				  for (i = 0; i < G_N_ELEMENTS (lastfm_retry_error_codes); i++) {
+				    if (code == lastfm_retry_error_codes[i]) {
+				      rb_debug ("Received retry error code. will try again");
+				      request_session_key_timeout_cb(account);
+				      break;
+				    }
+				  }
+				}
+			  
 				/* some other error. most likely 4 (invalid token) or 15 (token has expired)
 				 * whatever it is, we wont be retrieving a session key from it
 				 */
-				rb_debug ("error retrieving session key: %s", message);
+				rb_debug ("error retrieving session key. logging out");
 
 				/* go back to being logged out */
 				rb_audioscrobbler_account_logout (account);
diff --git a/plugins/audioscrobbler/rb-audioscrobbler-service.c b/plugins/audioscrobbler/rb-audioscrobbler-service.c
index b3bd80a..d22bfa5 100644
--- a/plugins/audioscrobbler/rb-audioscrobbler-service.c
+++ b/plugins/audioscrobbler/rb-audioscrobbler-service.c
@@ -29,8 +29,7 @@
 #include "rb-audioscrobbler-service.h"
 
 /* Last.fm details */
-#define LASTFM_NAME "Last.fm"
-#define LASTFM_AUTH_URL "http://www.last.fm/api/auth/"
+#define LASTFM_AUTH_URL "https://www.last.fm/api/auth/"
 #define LASTFM_SCROBBLER_URL "http://post.audioscrobbler.com/"
 #define LASTFM_API_URL "http://ws.audioscrobbler.com/2.0/"
 #define LASTFM_OLD_RADIO_API_URL "http://ws.audioscrobbler.com/"
@@ -39,7 +38,6 @@
 #define LASTFM_API_KEY "0337ff3c59299b6a31d75164041860b6"
 #define LASTFM_API_SECRET "776c85a04a445efa8f9ed7705473c606"
 
-#define LIBREFM_NAME "Libre.fm"
 #define LIBREFM_AUTH_URL "http://alpha.libre.fm/api/auth/"
 #define LIBREFM_SCROBBLER_URL "http://turtle.libre.fm/"
 #define LIBREFM_API_URL "http://alpha.libre.fm/2.0/"
diff --git a/plugins/audioscrobbler/rb-audioscrobbler-service.h b/plugins/audioscrobbler/rb-audioscrobbler-service.h
index 45edf53..30f1f73 100644
--- a/plugins/audioscrobbler/rb-audioscrobbler-service.h
+++ b/plugins/audioscrobbler/rb-audioscrobbler-service.h
@@ -31,6 +31,9 @@
 
 #include <glib-object.h>
 
+#define LASTFM_NAME "Last.fm"
+#define LIBREFM_NAME "Libre.fm"
+
 /* not sure these belong here */
 #define AUDIOSCROBBLER_SETTINGS_SCHEMA "org.gnome.rhythmbox.plugins.audioscrobbler.service"
 #define AUDIOSCROBBLER_SETTINGS_PATH "/org/gnome/rhythmbox/plugins/audioscrobbler"
